我干了为什么-至少在.Net Framework中-在执行XPath查询时必须使用XmlNamespaceManager
来处理名称空间(或笨拙而冗长的[local-name()=...
XPath谓词/函数/其他) 。我不明白为什么命名空间是必要的,或者至少是有益的,但为什么会这样复杂?
为了查询一个简单的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://example.com/xmlns/foo">
<nodeName>Some Text Here</nodeName>
</rootNode>
...需要多几行代码才能获得相同的结果:
Dim nsmgr As New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("ab", "http://example.com/xmlns/foo")
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://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>
...如果我理解正确,则必须将两个名称空间都添加到中XmlNamespaceManager
,以便查询单个节点...
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)
...为什么在这种情况下,我(概念上)需要一个名称空间管理器?
******已编辑到下面的评论中****
编辑添加: 我经过修订和完善的问题是基于XmlNamespaceManager在我认为是大多数情况下的明显冗余以及使用命名空间管理器来指定前缀到URI的映射的基础:
当在源文档中明确声明名称空间前缀(“ cde”)到名称空间URI(“ http://example.com/xmlns/foo ”)的直接映射时:
...<rootNode xmlns:cde="http://example.com/xmlns/foo"...
程序员在进行查询之前重新创建该映射的概念需求是什么?