I've come up kinda dry as to why -- at least in the .Net Framework -- it is necessary to use an XmlNamespaceManager
in order to handle namespaces (or the rather clunky and verbose [local-name()=...
XPath predicate/function/whatever) when performing XPath queries. I do understand why namespaces are necessary or at least beneficial, but why is it so complex?
In order to query a simple XML Document (no namespaces)...
<?xml version="1.0" encoding="ISO-8859-1"?>
<rootNode>
<nodeName>Some Text Here</nodeName>
</rootNode>
...one can use something like doc.SelectSingleNode("//nodeName")
(which would match <nodeName>Some Text Here</nodeName>
)
Mystery #1: My first annoyance -- If I understand correctly -- is that merely adding a namespace reference to the parent/root tag (whether used as part of a child node tag or not) like so:
<?xml version="1.0" encoding="ISO-8859-1"?>
<rootNode xmlns="http://example.com/xmlns/foo">
<nodeName>Some Text Here</nodeName>
</rootNode>
...requires several extra lines of code to get the same result:
Dim nsmgr As New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("ab", "http://example.com/xmlns/foo")
Dim desiredNode As XmlNode = doc.SelectSingleNode("//ab:nodeName", nsmgr)
...essentially dreaming up a non-existent prefix ("ab
") to find a node that doesn't even use a prefix. How does this make sense? What is wrong (conceptually) with doc.SelectSingleNode("//nodeName")
?
Mystery #2: So, say you've got an XML document that uses prefixes:
<?xml version="1.0" encoding="ISO-8859-1"?>
<rootNode xmlns:cde="http://example.com/xmlns/foo" xmlns:feg="http://example.com/xmlns/bar">
<cde:nodeName>Some Text Here</cde:nodeName>
<feg:nodeName>Some Other Value</feg:nodeName>
<feg:otherName>Yet Another Value</feg:otherName>
</rootNode>
... If I understand correctly, you would have to add both namespaces to the XmlNamespaceManager
, in order to make a query for a single node...
Dim nsmgr As New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("cde", "http://example.com/xmlns/foo")
nsmgr.AddNamespace("feg", "http://example.com/xmlns/bar")
Dim desiredNode As XmlNode = doc.SelectSingleNode("//feg:nodeName", nsmgr)
... Why, in this case, do I need (conceptually) a namespace manager?
******REDACTED into comments below****
Edit Added: My revised and refined question is based upon the apparent redundancy of the XmlNamespaceManager in what I believe to be the majority of cases and the use of the namespace manager to specify a mapping of prefix to URI:
When the direct mapping of the namespace prefix ("cde") to the namespace URI ("http://example.com/xmlns/foo") is explicitly stated in the source document:
...<rootNode xmlns:cde="http://example.com/xmlns/foo"...
what is the conceptual need for a programmer to recreate that mapping before making a query?