XML文档中的某些节点具有命名空间,使用已定义的前缀指定。
可以在XPath 1.0中指定 local-name(),因此忽略名称空间。
但是,我想让XPath的编写者使用其完整的名称空间限定名称作为标识符来查找节点。
推荐的方法是在调用代码中添加名称空间声明(在我的例子中是Java)。但这意味着编写Xpath的人无法使用命名空间!
我们如何使用纯XPath通过其完全限定名称查找节点?
答案 0 :(得分:14)
不确定“作为标识符”是什么意思。
我们如何使用纯XPath通过其完全限定名称查找节点?
在XPath 1.0中,使用local-name()和namespace-uri(),例如
"*[local-name() = 'foo' and namespace-uri() = 'http://my.org/ns/2.0']"
在XPath 2.0中,有一组与名称空间相关的更丰富的函数,例如: namespace-uri-from-QName()
。但我不确定他们是否会根据你的需要改进上述内容。
答案 1 :(得分:5)
XPath 3.0,目前处于工作草案状态,将包含URI qualified QNames的文字表达式,允许直接指定名称空间uri。
以下是EQNames的一些示例:
- pi是一个没有名称空间前缀的词汇QName。
- math:pi是带有名称空间前缀的词法QName。
- “http://www.w3.org/2005/xpath-functions/math”:pi使用URILiteral指定名称空间URI;它不是词汇QName。
我认为Saxon 9.3包含xpath 3.0的预览实现,它可以通过java api使用。
答案 2 :(得分:1)
您可以在XPath查询期间使用命名空间。在Java中,如果您还希望始终在这些查询中使用前缀而不是完全限定的命名空间,则需要提供的是NamespaceContext的实现。只需将NamespaceContext
的实例添加到XPath
- 我假设您使用标准的JDK实现 - 但这个概念也适用于Jaxen或其他人。
然后您可以执行//customns:Element
等查询。
如果您没有或不能使用NamespaceContext
(无论出于何种原因),那么唯一的解决方案似乎是使用local-name
和namespace-uri
函数:
Document doc = ...;
XPath xp = XPathFactory.newInstance().newXPath();
String name = "Element";
String ns = "http://www.custom.org/#";
String expr = "//*[local-name() = '"+name+" and namespace-uri() = '"+ns+"']";
Node node = ((NodeList)xp.evaluate(expr, doc, XPathConstants.NODESET)).item(0);
答案 3 :(得分:0)
XPath 3.0的规范说:
Q{http://www.w3.org/2005/xpath-functions/math}pi
此时此工作(2015年10月),例如在eXist-db中。