2016-09-30 60 views
0
<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消息的SOAP消息解析使用XPath在Java中

SOAPMessage soapMessage = getSoapMessage()

我想要做的是能够运行的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);

似乎工作正常。我的问题是,如何正确设置命名空间上下文,以便我可以使用xPath查询而不在每个节点周围都有name()=...?我是否需要使用DocumentBuilder工厂并将其名称空间设置为true?如果是这样,我该如何将这个SOAP消息加入该工厂?

+1

'xPath.compile(“/ whatever:ParentNode”)'? – har07

+0

恐怕我不明白,什么是标签?如果这是你的意思,似乎没有所需命名空间的前缀。 – vkuo

回答

0

由于har07建议,加入任意前缀我的XPath查询被招将我的名字空间得到妥善解决。因此,以下查询工作:

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