XPATHS и пространства имен по умолчанию

Какова история XPath и поддержка пространств имен? XPath как спецификация предшествует пространствам имен? Если у меня есть документ, где элементам присваивается пространство имен по умолчанию:

<foo xmlns="uri" />

Кажется, что некоторые из процессорных библиотек XPath не распознают //foo из-за пространства имен, тогда как другие будут. Опция, которую моя команда задумала, заключается в добавлении префикса пространства имен с использованием регулярных выражений в XPath (вы можете добавить префикс пространства имен через XmlNameTable), но это кажется хрупким, поскольку XPath является таким гибким языком, когда дело доходит до тестов node.

Есть ли стандарт, который применим к этому?

Мой подход немного хакерский, но, похоже, он работает нормально; Я удаляю объявление xmlns с помощью поиска/замены, а затем применяю XPath.

string readyForXpath = Regex.Replace(xmldocument, "xmlns=\".+\"", String.Empty );

Это справедливый подход или кто-то решил это по-другому?

Ответ 1

Я попробовал что-то похожее на то, что предложил палевый хор, и не мог заставить его работать. Поскольку я получал данные из опубликованной службы, я не мог изменить 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

Ответ 3

Проблема заключается в том, что элемент без пространства имен объявлен в пространстве имен NULL, поэтому если //foo сопоставлено с пространством имен, которое вы считаете "по умолчанию", не было бы способа ссылаться на элемент в пустое пространство имен.

Помните также, что префикс для пространства имен является только сокращенным соглашением, реальное имя элемента (Квалифицированное имя или QName для краткости) состоит из полного пространства имен и локального имени. Изменение префикса для пространства имен не изменяет "идентификатор" элемента - если оно находится в одном и том же пространстве имен и том же локальном имени, то это тот же самый элемент, даже если префикс отличается.

XPath 2.0 (или, скорее, XSLT 2.0) имеет концепцию "пространства имен xpath по умолчанию". Вы можете установить атрибут xpath-default-namespace в элементе xsl: stylesheet.

Ответ 4

Если вы пытаетесь использовать xslt, вы можете добавить пространство имен в объявление стилей. Если вы это сделаете, вы должны убедиться, что есть префикс, или он не будет работать. Если исходный XML не имеет префикса, это все равно, вы добавляете свой собственный префикс в таблицу стилей.

Stylesheet

<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>

Или что-то в этом роде.