使用javax.xml.xpath无法从W3C XML文档中找到元素的问题排查
问题原因与解决方法
你的XML使用了sqph命名空间,但当前代码里的XPath没有绑定对应的命名空间URI,导致无法匹配到带命名空间的元素,所以返回的节点列表、节点和字符串都为空。
解决方法有两种,推荐第一种(可读性更高):
方法一:绑定命名空间上下文
- 实现
NamespaceContext接口,映射前缀sqph到对应的命名空间URI:
import javax.xml.namespace.NamespaceContext; import javax.xml.XMLConstants; import java.util.Collections; import java.util.Iterator; NamespaceContext nsContext = new NamespaceContext() { @Override public String getNamespaceURI(String prefix) { if ("sqph".equals(prefix)) { return "http://schemas.company.com/office/placeholders/v1"; } return XMLConstants.NULL_NS_URI; } @Override public String getPrefix(String namespaceURI) { if ("http://schemas.company.com/office/placeholders/v1".equals(namespaceURI)) { return "sqph"; } return null; } @Override public Iterator getPrefixes(String namespaceURI) { return Collections.singletonList("sqph").iterator(); } };
- 给XPath对象设置这个命名空间上下文,再执行查询:
XPath xpath = XPathFactory.newInstance().newXPath(); xpath.setNamespaceContext(nsContext); // 这是关键步骤 XPathExpression expr = xpath.compile("/sqph:contractplaceholders[1]/sqph:ContractMgmt_ContractNumber[1]/text()"); // 后续查询代码不变 NodeList nodeList = (NodeList) expr.evaluate(docXml, XPathConstants.NODESET); org.w3c.dom.Node node = (org.w3c.dom.Node) expr.evaluate(docXml, XPathConstants.NODE); String str = (String) expr.evaluate(docXml, XPathConstants.STRING);
方法二:使用通配符匹配(可读性差,不推荐)
如果不想实现NamespaceContext,可以修改XPath表达式,通过namespace-uri()和local-name()函数匹配元素,无需依赖前缀:
/*[namespace-uri()='http://schemas.company.com/office/placeholders/v1' and local-name()='contractplaceholders'][1]/*[namespace-uri()='http://schemas.company.com/office/placeholders/v1' and local-name()='ContractMgmt_ContractNumber'][1]/text()
内容的提问来源于stack exchange,提问作者Luis Alfredo Conde Vela
相关产品推荐
相关产品推荐

