Какова история XPath и поддержки пространств имен? XPath как спецификация предшествовал пространствам имен? Если у меня есть документ, в котором элементам задано пространство имен по умолчанию:
<foo xmlns="uri" />
Похоже, что некоторые библиотеки процессора XPath не распознают //foo
из-за пространства имен, тогда как другие будут. Моя команда подумала о том, чтобы добавить префикс пространства имен с помощью регулярных выражений в XPath (вы можете добавить префикс пространства имен через XmlNameTable), но это кажется хрупким, поскольку XPath является таким гибким языком, когда дело доходит до тестов узлов.
Есть ли стандарт, который применим к этому?
Мой подход немного хакерский, но, кажется, работает нормально; Я удаляю объявление xmlns
с поиском / заменой, а затем применяю XPath.
string readyForXpath = Regex.Replace(xmldocument, "xmlns=\".+\"", String.Empty );
Это справедливый подход, или кто-то решил это по-другому?
Я попробовал что-то подобное тому, какой предложенный palehorse и не мог заставить его работать. Так как я получал данные из опубликованного сервиса, я не мог изменить xml. Я закончил тем, что использовал XmlDocument и XmlNamespaceManager как так:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlWithBogusNamespace);
XmlNamespaceManager nSpace = new XmlNamespaceManager(doc.NameTable);
nSpace.AddNamespace("myNs", "http://theirUri");
XmlNodeList nodes = doc.SelectNodes("//myNs:NodesIWant",nSpace);
//etc
Проблема - то, что элемент без пространства имен, как объявляют, находится в ПУСТОМ пространстве имен - поэтому, если бы//нечто соответствовало против пространства имен, Вы считаете 'значением по умолчанию' не было бы никакого способа относиться к элементу в пустом пространстве имен.
Помнят также, что префикс для пространства имен является только соглашением стенографии, реальное имя элемента (Полностью определенное имя или QName, если коротко) состоит из полного пространства имен и локального имени. Изменение префикса для пространства имен не изменяет 'идентификационные данные' элемента - если это находится в том же пространстве имен и том же локальном имени тогда, это - тот же вид элемента, даже если префикс отличается.
XPath 2.0 (или скорее XSLT 2.0) имеет понятие 'значения по умолчанию xpath пространство имен'. Можно установить атрибут xpath-пространства-имен-по-умолчанию на xsl:stylesheet элементе.
При попытке использовать xslt, можно включить пространство имен к объявлению таблицы стилей. Если Вы делаете это, необходимо удостовериться, что существует префикс, или он не будет работать. Если источник, XML не имеет префикса, который прекрасен все еще, Вы добавляете свой собственный префикс в таблице стилей.
Таблица стилей
<xsl:stylesheet
xmlns:fb="uri"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="fb:foo/bar">
<!-- do stuff here -->
</xsl:template>
</xsl:stylsheet>
Или что-то как этот.
Вам нужно локальное имя ():
http://www.w3.org/TR/xpath#function-local-name
Для закрепления от http://jcooney.net/archive/2005/08/09/6517.aspx :
<foo xmlns='urn:foo'>
<bar>
<asdf/>
</bar>
</foo>
Это выражение будет соответствовать элементу “bar”:
//*[local-name()='bar']
Этот не будет:
//bar
xml.SelectNodes("kml:kml/kml:Document/kml:Folder", manager)
– Drew Noakes 15.12.2019, 12:07