.net – 为什么需要XmlNamespaceManager?
我为什么 – 为什么 – 至少在.Net框架 – 有必要使用一个XmlNamespaceManager为了处理命名空间(或相当clunky和verbose [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://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) …为什么,在这种情况下,我需要(概念上)一个命名空间管理器? **已删除到以下评论** 编辑已添加: 当在源文档中明确说明命名空间前缀(“cde”)到命名空间URI(“http://someplace.org”)的直接映射时: ...<rootNode xmlns:cde="http://someplace.org"... 在进行查询之前,程序员需要重新创建该映射的概念性需求是什么?
基本点(如
Kev,above所指出的),是命名空间URI是命名空间的重要部分,而不是命名空间前缀,前缀是“任意便利”
至于为什么你需要一个命名空间管理器,而不是有一些魔术,它使用文档,我可以想到两个原因。 原因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表达式。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |