gpt4 book ai didi

.net - 为什么需要 XmlNamespaceManager?

转载 作者:行者123 更新时间:2023-12-03 05:32:48 25 4
gpt4 key购买 nike

对于为什么(至少在 .Net Framework 中),我已经有点干巴巴地想出了为什么有必要使用 XmlNamespaceManager 。为了在执行 XPath 查询时处理 namespace (或相当笨重和冗长的 [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"...

程序员在进行查询之前重新创建该映射的概念需求是什么?

最佳答案

基本点(正如 Kev, above 所指出的),是命名空间 URI 是命名空间的重要组成部分,而不是命名空间前缀,前缀是一种“任意便利”

至于为什么需要命名空间管理器,而不是使用文档来解决它,我可以想到两个原因。

原因 1

如果只允许向 documentElement 添加 namespace 声明(如您的示例中所示),那么 selectSingleNode 仅使用定义的任何内容确实很简单。

但是,您可以在文档中的任何元素上定义命名空间前缀,并且命名空间前缀不会唯一绑定(bind)到文档中的任何给定命名空间。考虑以下示例

<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 返回什么?如果没有某种外部 namespace 管理器,您将如何表达这一点?

原因 2

它允许您对任何等效文档重用相同的 XPath 表达式,而无需了解有关所使用的命名空间前缀的任何信息。

myXPathExpression = "//z:y"
doc1.selectSingleNode(myXPathExpression);
doc2.selectSingleNode(myXPathExpression);

文档1:

<x>
<z:y xmlns:z="mynamespace" />
</x>

文档2:

<x xmlns"mynamespace">
<y>
</x>

为了在没有 namespace 管理器的情况下实现后一个目标,您必须检查每个文档,为每个文档构建自定义 XPath 表达式。

关于.net - 为什么需要 XmlNamespaceManager?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7178111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com