为了查询一个简单的XML文档(没有命名空间)…
<?xml version="1.0" encoding="ISO-8859-1"?> <rootNode> <nodeName>Some Text Here</nodeName> </rootNode>
…可以使用像doc.SelectSingleNode(“// nodeName”)(这将与< nodeName> Some Text Here< / nodeName>匹配)
神秘#1:我的第一烦恼 – 如果我理解正确 – 只是添加一个命名空间引用父/根标记(无论是否作为子节点标记的一部分),如:
<?xml version="1.0" encoding="ISO-8859-1"?> <rootNode xmlns="http://someplace.org"> <nodeName>Some Text Here</nodeName> </rootNode>
…需要几行额外的代码才能得到相同的结果:
Dim nsmgr As New XmlNamespaceManager(doc.NaMetable) nsmgr.AddNamespace("ab","http://s+omeplace.org") Dim desiredNode As XmlNode = doc.SelectSingleNode("//ab:nodeName",nsmgr)
…基本上在做一个不存在的前缀(“ab”)来找到一个甚至不使用前缀的节点。这是怎么回事?使用doc.SelectSingleNode(“// nodeName”)有什么问题(概念上)?
神秘#2:所以,假设你有一个使用前缀的XML文档:
<?xml version="1.0" encoding="ISO-8859-1"?> <rootNode xmlns:cde="http://someplace.org" xmlns:feg="http://otherplace.net"> <cde:nodeName>Some Text Here</cde:nodeName> <feg:nodeName>Some Other Value</feg:nodeName> <feg:otherName>Yet Another Value</feg:otherName> </rootNode>
…如果我理解正确,你必须添加两个名称空间到XmlNamespaceManager,以便查询单个节点…
Dim nsmgr As New XmlNamespaceManager(doc.NaMetable) nsmgr.AddNamespace("cde","http://someplace.org") nsmgr.AddNamespace("feg","http://otherplace.net") Dim desiredNode As XmlNode = doc.SelectSingleNode("//feg:nodeName",nsmgr)
…为什么,在这种情况下,我需要(概念上)一个命名空间管理器?
编辑已添加:
我修改和细化的问题是基于XmlNamespaceManager的明显冗余,我相信是大多数情况下和使用命名空间管理器指定前缀到URI的映射:
当在源文档中明确说明命名空间前缀(“cde”)到命名空间URI(“http://someplace.org”)的直接映射时:
...<rootNode xmlns:cde="http://someplace.org"...
在进行查询之前,程序员需要重新创建该映射的概念性需求是什么?
至于为什么你需要一个命名空间管理器,而不是有一些魔术,它使用文档,我可以想到两个原因。
原因1
如果允许只向documentElement添加命名空间声明,就像在你的例子中一样,selectSingleNode只是使用定义的东西确实是微不足道的。
但是,您可以在文档中的任何元素上定义命名空间前缀,并且命名空间前缀不会唯一绑定到文档中的任何给定命名空间。请考虑以下示例
<w xmlns:a="mynamespace"> <a:x> <y xmlns:a="myOthernamespace"> <z xmlns="mynamespace"> <b:z xmlns:b="mynamespace"> <z xmlns="myOthernamespace"> <b:z xmlns:b="myOthernamespace"> </y> </a:x> </w>
在这个例子中,你想要什么// z,// a:z和// b:z返回?如何,没有某种外部命名空间管理器,你会表达吗?
原因2
它允许您为任何等效文档重用相同的XPath表达式,而不需要知道任何关于正在使用的命名空间前缀。
myXPathExpression = "//z:y" doc1.selectSingleNode(myXPathExpression); doc2.selectSingleNode(myXPathExpression);
doc1:
<x> <z:y xmlns:z="mynamespace" /> </x>
doc2:
<x xmlns"mynamespace"> <y> </x>
为了实现没有命名空间管理器的后一个目标,你必须检查每个文档,为每个文档构建一个自定义的XPath表达式。