Почему атрибут 'xmlns' влияет на поиск узла XPath? - PullRequest
5 голосов
/ 18 января 2011

Следующий код работает отлично. См. XML-файл ниже.

XPathDocument xPathDoc = new XPathDocument(@"C:\Authors.xml");
XPathNavigator navigator = xPathDoc.CreateNavigator();
XPathNodeIterator iterator = navigator.Select("/Contacts/Author/FirstName");
iterator.MoveNext();
string firstName = iterator.Current.InnerXml;
Console.WriteLine(firstName);

Значение 'firstName' возвращает 'Joe', что идеально. Однако, когда я добавляю это attibute xmlns = "http://www.w3.org/1999/xhtml" в тег '', чтобы он выглядел следующим образом:

<Author xmlns="http://www.w3.org/1999/xhtml">

тогда код не возвращает правильное значение («Джо») Почему тогда атрибут xmlns = "http://www.w3.org/1999/xhtml" влияет на приведенный выше код и что мне не хватает, чтобы вернуть правильное значение?

Любая помощь будет принята с благодарностью.

Вот XML-файл:

<?xml version="1.0" encoding="UTF-8" ?> 
<Contacts>
<Author>
<FirstName>Joe</FirstName>
</Author>
<Teacher>
<FirstName>Larry</FirstName>
</Teacher>

<Painter>
<FirstName>Mary</FirstName>
</Painter>
</Contacts>

Ответы [ 2 ]

7 голосов
/ 18 января 2011

xmlns - это пространство имен, которое используется, чтобы избежать конфликта между тегами xml. Сценарий, когда одно приложение использует XML из нескольких источников и один и тот же тэг существует в двух или более файлах XML. Поскольку вероятность такой неоднозначности высока, для ее уменьшения используется пространство имен.

5 голосов
/ 18 января 2011

Ваше выражение XPath ищет элементы "Контакты", "Автор" и "Имя_папки" без пространств имен .Похоже, элемент Author (и любые элементы-потомки, у которых нет объявления пространства имен) do имеют пространства имен, не соответствует ли ваше выражение XPath.

Чтобы исправитьвам нужно будет использовать XmlNamespaceManager, связать префикс с пространством имен и включить это пространство имен в выражение XPath.Честно говоря, это становится грязно.

Есть ли причина, по которой вы не можете использовать LINQ to XML вместо этого?Это значительно упрощает работу с XML в целом и пространствами имен в частности.Я рад предложить образец LINQ to XML, если вы сможете его использовать.

РЕДАКТИРОВАТЬ: Вот пример LINQ to XML:

XDocument doc = XDocument.Load("authors.xml");
XNamespace ns = "http://www.w3.org/1999/xhtml";
var query = doc.Root
               .Elements(ns + "Author")
               .Elements(ns + "FirstName");
foreach (var element in query)
{
    Console.WriteLine((string) element);
}
...