1

我在我的应用程序中使用 XML XPath API

这是我的肥皂请求

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tes="http://testwork/">
       <soapenv:Header/>
       <soapenv:Body>
          <tes:sayHelloWorldFrom>
             <!--Optional:-->
             <arg0>value</arg0>
          </tes:sayHelloWorldFrom>
       </soapenv:Body>
    </soapenv:Envelope>

我想从此消息中检索正文,因此我想要

<soapenv:Body>
          <tes:sayHelloWorldFrom>
             <!--Optional:-->
             <arg0>value</arg0>
          </tes:sayHelloWorldFrom>
 </soapenv:Body>

我的一段代码看起来像

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        org.w3c.dom.Document doc = null;
        try {
            doc = factory.newDocumentBuilder().parse(is);
            XPathFactory xFactory = XPathFactory.newInstance();
            XPath xPath = xFactory.newXPath();
            Object result = xPath.compile("/soapenv:Envelope/soapenv:Body").evaluate(doc, XPathConstants.NODESET);
            NodeList nodes = (NodeList) result;
            log.info("result " + nodes);

但结果是 result com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList@19f76837

那么我做错了什么?

4

1 回答 1

4

XPathConstants.NODESET指示 API 返回NodeList它找到的与查询匹配的结果。

当您期望有可变数量的匹配时,这很有用。您可以遍历列表...

for (int index = 0; index < nodes.getLength(); index++) {
    Node node = nodes.item(index);
    //...
}

如果你确信你只会收到一个结果(或者你只想要第一个匹配),你可以XPathConstants.NODE使用

Object result = xPath.compile("/soapenv:Envelope/soapenv:Body").evaluate(doc, XPathConstants.NODE);
Node node = (Node)result;

更新

如果不执行以下操作,可能就可以做到这一点,但名称空间让我很头疼……

创建factory, set it's name space awareness tofalse 后,然后从搜索中删除节点名称空间上下文,例如...

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
org.w3c.dom.Document doc = null;
try {
    doc = factory.newDocumentBuilder().parse(new File("Soap.xml"));

    XPathFactory xFactory = XPathFactory.newInstance();
    XPath xPath = xFactory.newXPath();
    Object result = xPath.compile("/Envelope/Body").evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;
    System.out.println("Found " + nodes.getLength() + " matches");
    for (int index = 0; index < nodes.getLength(); index++) {
        Node node = nodes.item(index);
        System.out.println(node);
    }
} catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException exp) {
    exp.printStackTrace();
}
于 2013-10-11T00:33:26.197 回答