对于给定的XML和XPath,在线XPath测试程序的工作方式类似于我的代码(不匹配任何内容):http://www.xpathtester.com/xpath
import java.io.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
class test {
public static void main(String[] args) throws Exception {
XPathExpression expr = XPathFactory.newInstance().newXPath().compile(
"/A[namespace-uri() = 'some-namespace']"); // This does not select anything, replacing A with * does
// This XPath selects as expected (in all parsers mentioned): /*[namespace-uri() = 'some-namespace']
String xml = "<A xmlns=\"some-namespace\"> </A>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
System.out.println("Number of nodes selected: " + nodes.getLength());
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("Node name: " + nodes.item(i).getNodeName());
}
}
}
无论文档工厂是否支持名称空间,上述代码都不会选择任何内容。
这是根据XPath标准吗?或实施的细微差别?
This资源提及以下内容:
实际上,当XML文档使用默认命名空间时,XPath 表达式必须使用前缀,即使目标文档没有。
为了验证这一点,我更改了XPath以包含这样的前缀:
/p:A[namespace-uri() = 'some-namespace']
并添加了一个命名空间解析程序,它返回URI some-namespace ,用于前缀 p ,并且有效。
1)有没有办法让没有前缀的XPath表达式适用于具有默认命名空间的文档?
2)[第二个XPath测试人员] [3]如何工作? (该测试仪不符合标准)
注意:在我的应用程序中,我无法控制收到的文档和XPath。但两者都保证有效。
答案 0 :(得分:1)
对于您的示例XML,
<root>
<A xmlns="some-namespace"> </A>
<A xmlns="some-namespace2"> </A>
</root>
这个XPath,
//A
应该选择 ,但在Freeformatter.com上,它会选择
<A xmlns="some-namespace2"> </A>
错误 。
因此,全面停止,不要使用 Freeformatter.com 。不要试图解决这个问题 - 只是不要使用该服务,因为不能信任它以一致的方式评估XPath。
1)有没有办法让没有前缀的XPath表达式适用于具有默认命名空间的文档?
你可以
local-name()
[不推荐] local-name()
和namespace-uri()
[确定,但详细]或有关详细信息,包括如何在许多不同托管语言中定义名称空间前缀的示例,请参阅 How does XPath deal with XML namespaces?
在我的应用程序中,我无法控制我收到的文档和XPath(它保证有效)。所以我必须处理发送给我的XPath。我猜测我的问题的答案是不会的。?
如果您正在询问是否有//A
从上面的示例XML中选择节点并且仍然符合XPath的方法,那么答案确实是 no < /强>