Использование Xpath с пространством имен по умолчанию в C # - PullRequest
59 голосов
/ 25 февраля 2009

У меня есть документ XML с пространством имен по умолчанию. Я использую XPathNavigator для выбора набора узлов с помощью Xpath следующим образом:

XmlElement myXML = ...;  
XPathNavigator navigator = myXML.CreateNavigator();
XPathNodeIterator result = navigator.Select("/outerelement/innerelement");

Я не получаю никаких результатов: я предполагаю, что это потому, что я не указываю пространство имен. Как я могу включить пространство имен в свой выбор?

Ответы [ 13 ]

1 голос
/ 20 октября 2010

Я использовал хакерский, но полезный подход, описанный SpikeDog выше. Он работал очень хорошо, пока я не бросил в него выражение xpath, которое использовало каналы для объединения нескольких путей.

Поэтому я переписал его, используя регулярные выражения, и подумал, что поделюсь:

public string HackXPath(string xpath_, string prefix_)
{
    return System.Text.RegularExpressions.Regex.Replace(xpath_, @"(^(?![A-Za-z0-9\-\.]+::)|[A-Za-z0-9\-\.]+::|[@|/|\[])(?'Expression'[A-Za-z][A-Za-z0-9\-\.]*)", x =>
                {
                    int expressionIndex = x.Groups["Expression"].Index - x.Index;
                    string before = x.Value.Substring(0, expressionIndex);
                    string after = x.Value.Substring(expressionIndex, x.Value.Length - expressionIndex);
                    return String.Format("{0}{1}:{2}", before, prefix_, after);
                });
}
0 голосов
/ 10 января 2019

1] Если у вас есть XML-файл без префикса в пространстве имен:

<bookstore xmlns="http://www.contoso.com/books">
…
</bookstore>

у вас есть этот обходной путь:

XmlTextReader reader = new XmlTextReader(@"C:\Temp\books.xml");
// ignore the namespace as there is a single default namespace:
reader.Namespaces = false;
XPathDocument document = new XPathDocument(reader);
XPathNavigator navigator = document.CreateNavigator();
XPathNodeIterator nodes = navigator.Select("//book");

2] Если у вас есть XML-файл с префиксом в пространстве имен:

<bookstore xmlns:ns="http://www.contoso.com/books">
…
</bookstore>

Используйте это:

XmlTextReader reader = new XmlTextReader(@"C:\Temp\books.xml");
XPathDocument document = new XPathDocument(reader);
XPathNavigator navigator = document.CreateNavigator();
XPathNodeIterator nodes = navigator.Select("//book");

Конечно, вы можете использовать управление именами в случае необходимости:

XmlTextReader reader = new XmlTextReader(@"C:\Temp\books.xml");
XPathDocument document = new XPathDocument(reader);
XPathNavigator navigator = document.CreateNavigator();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(reader.NameTable);
nsmgr.AddNamespace("ns", "http://www.contoso.com/book");
XPathNodeIterator nodes = navigator.Select("//book", nsmgr);

Я думаю, что в большинстве случаев это самый простой способ заставить код работать.

Я надеюсь, что это поможет решить эту проблему Microsoft ...

0 голосов
/ 25 февраля 2009

В этом случае, вероятно, причиной проблемы является разрешение пространства имен, но также возможно, что ваше выражение XPath само по себе неверно. Вы можете сначала оценить его.

Вот код, использующий XPathNavigator.

//xNav is the created XPathNavigator.
XmlNamespaceManager mgr = New XmlNamespaceManager(xNav.NameTable);
mgr.AddNamespace("prefix", "http://tempuri.org/");

XPathNodeIterator result = xNav.Select("/prefix:outerelement/prefix:innerelement", mgr);
...