c# - 为什么我需要为 Xpath 查询指定命名空间管理器

标签 c# xml

查询 XmlDocument 时,我需要在每次调用时传递命名空间管理器。确实很烦人,但这只是我们生活的一部分。真正烦人的一点是首先创建命名空间管理器。

XmlNamespaceManager nsMan = new XmlNamespaceManager(invoiceTextReader.NameTable);
nsMan.AddNamespace("", "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2");
nsMan.AddNamespace("pb", "urn:pierbridge:names:specification:pbl:schema:xsd:tpn-1");
...

要创建它,我不仅需要使用名称表为实例播种,还需要手动指定每个命名空间。这对我来说太愚蠢了。如果我必须去手动添加它们,那么传递名称表有什么意义呢?如果我需要为每个查询传回 namespace 管理器,那么传递名称表有什么意义呢?为什么它不能立即从文档中包含的内容构建命名空间管理器。似乎只是运行一个查询就需要大量的麻烦。

最佳答案

如果您的 XPath 具有命名空间前缀,则必须传入 NamespaceManager。以下是您不需要命名空间管理器的情况列表:

  • 如果您的所有节点都在默认(空)命名空间中,您可以使用 /a/b/c 作为 XPath
  • 如果您更喜欢为每个节点手动指定命名空间/名称对,例如 *[namespace-uri()='urn:oasis:names' & name()='node1']
  • 如果您只能在 XPath 中使用父/子、位置和兄弟

您传递 NameTable 以允许更快的字符串比较 - 如果文档和命名空间管理器共享相同的 NameTable,则相同的字符串实际上是相同的对象。您实际上不必传递相同的 NameTable。

您必须仅指定那些在您的 XPath 中使用的前缀。它通常远小于文档中的所有 namespace 。无法从 XML 自动计算映射,因为前缀到 namespace 的映射是任意的。

这是一个 XML 示例,其中所有前缀都相同,但每次都映射到不同的命名空间,以显示在 XPath 中自定义前缀映射的实际需要:

<a:a xmlns='a:my1'>
 <a:a xmlns='a:my2' />
 <a:a xmlns='a:my3' />
</a>

关于c# - 为什么我需要为 Xpath 查询指定命名空间管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7404386/

相关文章:

c# - 无法在 Azure 虚拟机上打开 TCP channel

c# - 在 linq 查询中转换泛型类型

c# - .NET Core WebAPI 中的 Fluent Validation 中间件是否足够,还是我应该再次在服务层中进行验证?

c# - 如何对 ASP.NET MVC View 进行 Web 测试?

c# - MVVM交叉更新错误: does not contain a definition for 'EndingWith' and no extension method 'EndingWith'

xml - 如何用定界符分隔 XPath 结果?

c# - 如何使用 LINQ 从 XML 文件中获取完整列表?

xml - 错误 : open Xml file wiht Chrome that contains spcials characters in namespaceURI

java - XML 资源中的变量 - 将值从父级传递给子级

XML XSD 命名空间问题