【问题标题】:Parsing a SOAP message using XPath in Java在 Java 中使用 XPath 解析 SOAP 消息
【发布时间】:2016-09-30 20:58:29
【问题描述】:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <ParentNode xmlns="http://namespace">
            <Status>Some_status</Satus>
            <Data>
                <Row>Some_row_data</Row>
            </Data>
        </ParentNode>
    </soap:Body>
</soap:Envelope>

在 API 调用中生成与上述结构相似的 SOAP 消息

SOAPMessage soapMessage = getSoapMessage()

我想要做的是能够在我的 sope 消息之上运行 xPath 查询,即我想在 Row 节点中获取数据。

我做了什么:

XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
xPath.setNamespaceContext(new NamespaceContext() {
      @Override
      public String getNamespaceURI(String prefix) {
        return "http://namespace";
      }

      @Override
      public String getPrefix(String namespaceURI) {
        return null;
      }

      @Override
      public Iterator getPrefixes(String namespaceURI) {
        System.out.println(namespaceURI);
        return null;
      }
    });

SOAPBody body = soapMessage.getSoapBody();
Document document = body.extractContentAsDocument();

NodeList list = (NodeList)xPath.compile("/").evaluate(document, XPathConstants.NODESET);
Node node = list.item(0);
System.out.println(node.getFirstChild().getNodeName());

在根节点上运行它一切正常,ParentNode 被打印到控制台。

但是,将我的 xPath 评估设置为以下内容:

NodeList list = (NodeList)xPath.compile("/ParentNode").evaluate(document, XPathConstants.NODESET);

导致一个空列表。我认为它与命名空间有关,所以我用以下内容替换了我的查询:

NodeList list = (NodeList)xPath.compile("/*[name()='ParentNode']").evaluate(document, XPathConstants.NODESET);

和 this 似乎工作正常。我的问题是,如何正确设置命名空间上下文,以便在没有 name()=... 围绕每个节点的情况下使用 xPath 查询?我是否需要使用 DocumentBuilder 工厂并将其命名空间感知设置为 true?如果是这样,我如何将此 SOAP 消息提供给该工厂?

【问题讨论】:

  • xPath.compile("/whatever:ParentNode") ?
  • 恐怕我不明白,whatever标签是什么?如果这就是您的意思,所需的命名空间似乎没有前缀。

标签: java xml soap


【解决方案1】:

正如har07 建议的那样,向我的xPath 查询添加任意前缀是正确解析我的命名空间的诀窍。结果,以下查询有效:

NodeList list = (NodeList)xPath.compile("/arbitraryprefix:ParentNode").evaluate(document, XPathConstants.NODESET);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-17
    相关资源
    最近更新 更多