使用XPath查询XML返回空字符串问题求助
解决XPath查询SOAP XML返回空的问题
你遇到的这个问题其实很典型——你的XPath表达式没处理XML里的命名空间,导致引擎识别不了带SOAP-ENV前缀的节点,自然返回空字符串。
先看你的示例XML结构:
<?xml version="1.0" encoding="UTF-8" ?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body></SOAP-ENV:Body> </SOAP-ENV:Envelope>
这里的SOAP-ENV是命名空间前缀,它对应的实际命名空间URI是http://schemas.xmlsoap.org/soap/envelope/。XPath引擎默认不知道前缀和URI的对应关系,直接用/SOAP-ENV:Envelope查询肯定找不到节点。
修正方案:绑定命名空间上下文
在Java代码里,你需要给XPath对象设置NamespaceContext,把前缀和对应的URI绑定起来,这样引擎才能正确解析带前缀的节点。下面是修正后的完整代码示例:
import javax.xml.namespace.NamespaceContext; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import org.xml.sax.InputSource; import java.io.StringReader; import java.util.Iterator; public static String getXPathValue(String stringSource) { try { XPath xpath = XPathFactory.newInstance().newXPath(); // 绑定SOAP-ENV前缀到对应的命名空间URI xpath.setNamespaceContext(new NamespaceContext() { @Override public String getNamespaceURI(String prefix) { if ("SOAP-ENV".equals(prefix)) { return "http://schemas.xmlsoap.org/soap/envelope/"; } return null; } @Override public String getPrefix(String namespaceURI) { if ("http://schemas.xmlsoap.org/soap/envelope/".equals(namespaceURI)) { return "SOAP-ENV"; } return null; } @Override public Iterator<String> getPrefixes(String namespaceURI) { return null; } }); String xpathExpr = "/SOAP-ENV:Envelope"; // 执行查询,获取节点的字符串表示(或者你可以根据需求获取Node对象) String result = xpath.evaluate(xpathExpr, new InputSource(new StringReader(stringSource))); return result; } catch (Exception e) { e.printStackTrace(); return ""; } }
额外小技巧
如果你不想绑定命名空间,也可以用另一种写法绕过前缀,直接匹配节点的本地名称和命名空间URI:
/*[local-name()='Envelope' and namespace-uri()='http://schemas.xmlsoap.org/soap/envelope/']
不过这种写法在多命名空间的XML里可读性较差,还是推荐绑定命名空间的方式更规范。
内容的提问来源于stack exchange,提问作者Adi
相关产品推荐
相关产品推荐

