来自带有命名空间前缀的 xml 的 xpath 表达式

Posted

技术标签:

【中文标题】来自带有命名空间前缀的 xml 的 xpath 表达式【英文标题】:xpath expression from xml with namespace prefix 【发布时间】:2011-04-25 07:31:15 【问题描述】:

当设置 xml 路径命名空间前缀时,我无法使以下 xpath 表达式工作。

/bk:BookStore/bk:Books/bk:Book[text()='Time Machine']

XML 是:

<BookStore xmlns:bk="http://www.bookstore.com/book#">
  <bk:Books>
    <bk:Book id="1">Time Machine></bk:Book>
  </bk:Books>
</bk:BookStore>

【问题讨论】:

发布执行 XPath 查询的代码。 您需要将前缀/命名空间-URI 绑定传递给您的 XPath 引擎。为什么?因为前缀对于名称测试并不重要,但命名空间 URI 很重要。所以a:node 可以选择b:node,只要ab 前缀绑定到同一个命名空间URI。 【参考方案1】:

如果没有关于宿主语言的更多信息(您尝试在其中评估 XPath 表达式)不可能提供有用的建议

一般来说,需要向命名空间管理器“注册”一个命名空间,这也将一个前缀关联到已注册的命名空间。然后,使用这个 NamespaceManager 对象作为 XPath 评估方法的参数,可以指定一个 XPath 表达式作为该方法的参数,其中包含以该特定前缀为前缀的名称。

解决方法

/*/*[name()='bk:Books']/*[name()='bk:Book' and text()='Time Machine']

【讨论】:

我在java中使用xml签名。我想在 trasnforms 部分选择要使用 xpath 签名的元素。当我的 xml 文档中有前缀和命名空间时,如何给出 xpath 表达式。 @Ashwin:这个答案准确地展示了如何做到这一点(一种可能的方式),而无需注册命名空间。第二种可能的方法是将名称空间注册到前缀绑定,其中 XPath 表达式中引用的元素名称是 - 然后 XPath 表达式可以包含前缀并且更具可读性。第二种方式需要用于注册实现提供的 API 的命名空间,并且需要阅读相应的文档。 更合适的“解决方法”类似于://*[fn:namespace-uri()="http://www.bookstore.com/book#" and local-name()='Book']。实际上,它甚至不是一种解决方法,只是一个冗长的 xpath。为简洁起见,有前缀,您用来执行 xpath 的环境应该为您提供一种指定它们的方法(xpath 中使用的前缀可以与 XML 文件中使用的前缀不同)。 @DavidL。这是一个有用的解决方法。但是,它对命名空间 uri 进行硬编码,如果命名空间本身被修改,则必须始终对其进行修改。想象一下必须维护许多这样的表达式。使用特定命名空间前缀的优点是在这种情况下只需要进行一次修改。【参考方案2】:

甚至更好(并且更便携),没有不必要的前缀:

/*/*[local-name()='Books'] ... and so on

The function local-name 忽略任何前缀,正如评论者正确指出的那样,前缀可能会有所不同。

【讨论】:

为什么有人反对这个?我发现这是一个很好的解决方案,可以避免处理命名空间,99% 的情况下命名空间只是烦人且不必要的。 如果命名空间只是你必须克服的障碍,是从外部强加给你的——通常是这样——那么这绝对是要走的路。

以上是关于来自带有命名空间前缀的 xml 的 xpath 表达式的主要内容,如果未能解决你的问题,请参考以下文章

使用XPath查询带有命名空间(有xmlns)的XML(转)

如何在具有默认命名空间的 xml 文档上使用 XPath

带有命名空间和前缀的 Json 到 XML

具有命名空间的 XML 文档上的 XPath

无法使用 DOM 解析器读取带有命名空间前缀的 xml

为啥命名空间限定节点没有 XPath 语法?