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

Dan*_*ell 5 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");
...
Run Code Online (Sandbox Code Playgroud)

要创建它,我不仅要使用nametable为实例设定种子,还要手动指定每个命名空间.这对我来说似乎很愚蠢.如果我必须手动添加它们,那么传递名称表的重点是什么.如果我需要为每个查询传递命名空间管理器,那么传递名称表的重点是什么.为什么它不能直接从文档中包含的内容构建命名空间管理器.看起来只是为了运行一个查询而烦恼不已.

Ale*_*kov 3

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

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

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

您必须仅指定 XPath 中使用的前缀。它通常比文档中的所有命名空间要少得多。由于命名空间映射的前缀是任意的,因此无法从 XML 自动计算映射。

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

<a:a xmlns='a:my1'>
 <a:a xmlns='a:my2' />
 <a:a xmlns='a:my3' />
</a>
Run Code Online (Sandbox Code Playgroud)