使用XPath和XML XPath Api获取Soap Body

时间:2013-10-11 00:19:15

标签: java xml soap xpath

我在我的应用程序中使用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

那么我做错了什么?

1 个答案:

答案 0 :(得分: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 to false`后,从搜索中删除节点名称空间上下文,例如......

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();
}