// This will fail with dotnet 3.5sp1. Why? //!!!! Assert.AreEqual(2, doc.SelectNodes("//b", nsmgr).Count);
This is a FAQ . XPath assumes that any unsigned name is in "no namespace." To select elements that belong to a namespace, in any XPath expression, their names must have a prefix with a prefix associated with that namespace. The AddNamespace() method serves precisely this purpose. It creates a binding between a specific namespace and a specific prefix. Then, if this prefix is used in an XPath expression, the element prefixed by it can be selected.
This is written in the XPath W3C specification : "The QName in the node test expands the expanded name using namespace declarations from the context of the expression. Similarly, the extension is performed for element type names in the start and end tags, except that the default namespace is declared using xmlns, is not used: if the QName does not have a prefix, then the namespace URI is null. "
See this at: w3.org/TR/xpath/#node-tests .
Thus, any unsigned name is considered "no namespace." The XML document provided does not have b elements in the "no namespace", and therefore the XPath //b expression does not select nodes at all.
Using
XmlNamespaceManager nsmanager = new XmlNamespaceManager(doc.NameTable); nsmanager.AddNamespace("x", "urn:test.Schema");
and then :
Assert.AreEqual(2, doc.SelectNodes("//x:b", nsmanager).Count);
Remember . The whole purpose of registering a namespace is to use a prefix (in this case, x ) in any XPath expression.
Dimitre Novatchev Nov 24 '10 at 21:54 2010-11-24 21:54
source share