// This will fail with dotnet 3.5sp1. Why?
//!!!!
Assert.AreEqual(2, doc.SelectNodes("//b", nsmgr).Count);
Это FAQ .В XPath предполагается, что любое имя без префикса находится в «пространстве имен».Чтобы выбрать элементы, которые принадлежат пространству имен, в любом выражении XPath их имена должны начинаться с префикса, связанного с этим пространством имен.Метод AddNamespace()
служит именно этой цели.Он создает связь между конкретным пространством имен и конкретным префиксом.Затем, если этот префикс используется в выражении XPath, можно выбрать элемент с префиксом.
Он записан в спецификации XPath W3C : "AQName в тесте узла раскрывается в расширенное имя с использованием объявлений пространства имен из контекста выражения.Так же как и расширение выполняется для имен типов элементов в начальных и конечных тегах за исключением того, что пространство имен по умолчанию, объявленное с помощью xmlns, не используется: если у QName нет префикса, то URI пространства имен имеет значение null ".
См. Это по адресу: w3.org / TR / xpath / # node-tests .
Таким образом, любое имя без префикса считается находящимся в «пространстве имен».В предоставленном XML-документе нет элементов b
в «пространстве имен», и поэтому выражение XPath //b
вообще не выбирает никаких узлов.
Использование :
XmlNamespaceManager nsmanager = new XmlNamespaceManager(doc.NameTable);
nsmanager.AddNamespace("x", "urn:test.Schema");
и позже :
Assert.AreEqual(2, doc.SelectNodes("//x:b", nsmanager).Count);
Помните : вся цель регистрации пространства имен состоит в том, чтобы иметь возможность использовать префикс (в этомcase x
) в любом выражении XPath.