来自带有命名空间前缀的 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
,只要a
和b
前缀绑定到同一个命名空间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 表达式的主要内容,如果未能解决你的问题,请参考以下文章