默认命名空间下无前缀XPath生效方案及非标准测试器原理问询
XPath与默认命名空间的匹配困惑
最近在处理XPath匹配带默认命名空间的XML时遇到了个棘手问题,想请教一下大家:
我写了一段Java代码,尝试用/A[namespace-uri() = 'some-namespace']这个XPath去匹配带有默认命名空间的<A xmlns="some-namespace"> </A>节点,但不管我有没有给DocumentBuilderFactory开启namespaceAware,都选不到任何节点——这和某在线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']"); // 替换成*就能正常选中节点:/*[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里的A换成*,写成/*[namespace-uri() = 'some-namespace'],就能正常匹配到节点;二是给XPath加上前缀,比如/p:A[namespace-uri() = 'some-namespace'],同时给XPath注册一个能把前缀p映射到some-namespace的命名空间解析器,也能正常工作。
现在我有两个正式的疑问:
- 是否存在无需前缀的XPath表达式,能在包含默认命名空间的文档上生效?
- 那款无法正常匹配的在线XPath测试器,它的工作原理是什么?为什么会和我Java代码的表现一致?
备注:我的应用无法控制接收的文档和XPath,但二者均保证合法。
内容的提问来源于stack exchange,提问作者Rushil Paul
相关产品推荐
相关产品推荐

