2015-11-02 69 views
-1

我有一個包含CDATA的soap響應,但是我在java中處理響應的所有開始引用(<)都被替換爲(<)。如何用Java SOAP響應中的(<)替換(<)SAAJ

這裏是響應應該怎麼看起來像

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
<soapenv:Body> 
    <ns:Response xmlns:ns="http://pipeline_ws"> 
    <ns:return> 
    <![CDATA[<fr><Result> 
     <ListPartner> 
      <operator> 
       <country_code></country_code> 
       <currency_code></currency_code> 
       <operator_code></operator_code> 

     </operator> 
    </ListPartner> 
</Result></fr>]]></ns:return> 
    </ns:Response> 
</soapenv:Body> 
</soapenv:Envelope> 

而是這是我得到

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
<soapenv:Body> 
    <ns:Response xmlns:ns="http://pipeline_ws"> 
     <ns:return> 
&lt;fr> 
&lt;Result> 
&lt;ListPartner> 
&lt;operator> 
&lt;country_code>&lt;/country_code> 
&lt;currency_code>&lt;/currency_code> 
&lt;operator_code>&lt;/operator_code> 
&lt;/operator> 
&lt;/ListPartner> 
&lt;/Result> 
&lt;/fr> 
    </ns:return> 
</ns:Response> 
</soapenv:Body> 
</soapenv:Envelope> 

請提供一個解決方案,刪除/替換不需要的字符幫助響應(< )所以我可以解析迴應。我使用SAAJ來處理響應

 // Process the SOAP Response 
SOAPMessage soapResponse = soapConnection.call(createSOAPRequest(), url); 
     soapResponse.writeTo(System.out); 
+1

兩個序列化實際上是相同的。您的結果將以字符串形式返回,而不是真正的XML。如果您對服務有控制權,您應該將其更改爲發送真正的XML。 – vanje

+0

@vanje我無法控制服務,所以我無法更改對XML的響應。 –

回答

0

解析XML和檢索<ns:return/>文本節點值的字符串。然後這個字符串可以被視爲XML。

final XPath xpath = XPathFactory.newInstance().newXPath(); 
xpath.setNamespaceContext(new MyNamespaceContext()); 
final String xmlFile = "1.xml"; 
final InputSource source = new InputSource(new FileInputStream(xmlFile)); 

final DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance(); 
fac.setNamespaceAware(true); 
final Document doc = fac.newDocumentBuilder().parse(source); 

final String result = (String) xpath.evaluate(
    "/soapenv:Envelope/soapenv:Body/pipeline:Response/pipeline:return/text()", 
    doc, XPathConstants.STRING); 

System.out.println(result); 

請注意,您應該在DocumentBuilderFactory實例中設置名稱空間感知。

這裏簡單NamespaceContext實現定義所需的空間前綴:

static class MyNamespaceContext implements NamespaceContext { 

    private Map<String, String> ns; 

    public MyNamespaceContext() { 
    ns = new HashMap<String, String>(); 
    ns.put("xs", "http://www.w3.org/2001/XMLSchema"); 
    ns.put("soapenv", "http://schemas.xmlsoap.org/soap/envelope/"); 
    ns.put("pipeline", "http://pipeline_ws"); 
    } 

    public String getNamespaceURI(String prefix) { 
    return ns.get(prefix); 
    } 

    public Iterator<String> getPrefixes() { 
    return ns.keySet().iterator(); 
    } 

    public Iterator<String> getPrefixes(String namespaceURI) { 
    final List<String> prefixes = new LinkedList<String>(); 
    if(namespaceURI != null) { 
     for(Entry<String, String> entry: ns.entrySet()) { 
     if(namespaceURI.equals(entry.getValue())) { 
      prefixes.add(entry.getKey()); 
     } 
     } 
    } 
    return prefixes.iterator(); 
    } 

    public Map<String, String> getPrefixMapping() { 
    return ns; 
    } 

    @Override 
    public String getPrefix(String namespaceURI) { 
    if(namespaceURI != null) { 
     for(Entry<String, String> entry: ns.entrySet()) { 
     if(namespaceURI.equals(entry.getValue())) { 
      return entry.getKey(); 
     } 
     } 
    } 
    return null; 
    }  
} 

第一個XML版本的輸出是:

<fr><Result> 
    <ListPartner> 
     <operator> 
      <country_code></country_code> 
      <currency_code></currency_code> 
      <operator_code></operator_code> 

    </operator> 
</ListPartner> 
</Result></fr> 

而對於第二:

<fr> 
<Result> 
<ListPartner> 
<operator> 
<country_code></country_code> 
<currency_code></currency_code> 
<operator_code></operator_code> 
</operator> 
</ListPartner> 
</Result> 
</fr>