.net – 为什么需要XmlNamespaceManager?

前端之家收集整理的这篇文章主要介绍了.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)

…为什么,在这种情况下,我需要(概念上)一个命名空间管理器?

**已删除到以下评论**

编辑已添加
修改和细化的问题是基于XmlNamespaceManager的明显冗余,我相信是大多数情况下和使用命名空间管理器指定前缀到URI的映射:

当在源文档中明确说明命名空间前缀(“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表达式。

猜你在找的XML相关文章