简体   繁体   English

用Java解析SOAP响应

[英]Parsing SOAP Response in Java

I do not succeed in parsing a SOAP Response in Java (using Bonita Open Solution BPM). 我无法使用Java(使用Bonita Open Solution BPM)解析SOAP响应。 I have the following SOAP response (searching for a document in the IBM Content Manager; the SOAP Response returns 1 matching document) 我有以下SOAP响应(在IBM Content Manager中搜索文档; SOAP响应返回1个匹配的文档)

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <ns1:RunQueryReply xmlns="http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema" xmlns:ns1="http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema">
         <ns1:RequestStatus success="true"></ns1:RequestStatus>
         <ns1:ResultSet count="1">
            <ns1:Item URI="http://xxxx/CMBSpecificWebService/CMBGetPIDUrl?pid=96 3 ICM8 ICMNLSDB16 ICCSPArchivSuche59 26 A1001001A12D18B30015E9357518 A12D18B30015E935751 14 1087&amp;server=ICMNLSDB&amp;dsType=ICM">
               <ns1:ItemXML>
                  <ICCSPArchivSuche ICCCreatedBy="EBUSINESS\iccadmin" ICCCreatedDate="2012-04-18T10:51:26.000000" ICCFileName="Golem_Artikel.txt" ICCFolderPath="" ICCLastModifiedDate="2012-04-18T10:51:28.000000" ICCLibrary="Dokumente" ICCModifiedBy="EBUSINESS\iccadmin" ICCSharePointGUID="c43f9c93-a228-43f9-8232-06bdea4695d1" ICCSharePointVersion="1.0   " ICCSite="Archiv Suche" cm:PID="96 3 ICM8 ICMNLSDB16 ICCSPArchivSuche59 26 A1001001A12D18B30015E9357518 A12D18B30015E935751 14 1087" xmlns:cm="http://www.ibm.com/xmlns/db2/cm/api/1.0/schema">
                     <cm:properties type="document">
                        <cm:lastChangeUserid value="ICCCMADMIN"/>
                        <cm:lastChangeTime value="2012-04-18T11:00:15.914"/>
                        <cm:createUserid value="ICCCMADMIN"/>
                        <cm:createTime value="2012-04-18T11:00:15.914"/>
                        <cm:semanticType value="1"/>
                        <cm:ACL name="DocRouteACL"/>
                        <cm:lastOperation name="RETRIEVE" value="SUCCESS"/>
                     </cm:properties>
                     <cm:resourceObject CCSID="0" MIMEType="text/plain" RMName="rmdb" SMSCollName="CBR.CLLCT001" externalObjectName=" " originalFileName="" resourceFlag="2" resourceName=" " size="702" textSearchable="true" xsi:type="cm:TextObjectType">
                        <cm:URL value="http://cmwin01.ebusiness.local:9080/icmrm/ICMResourceManager/A1001001A12D18B30015E93575.txt?order=retrieve&amp;item-id=A1001001A12D18B30015E93575&amp;version=1&amp;collection=CBR.CLLCT001&amp;libname=icmnlsdb&amp;update-date=2012-04-18+11%3A00%3A15.001593&amp;token=A4E6.IcQyRE6_QbBPESDGxK2;&amp;content-length=0"/>
                     </cm:resourceObject>
                  </ICCSPArchivSuche>
               </ns1:ItemXML>
            </ns1:Item>
         </ns1:ResultSet>
      </ns1:RunQueryReply>
   </soapenv:Body>
</soapenv:Envelope>

I would like to get the filename ( ICCFileName="Golem_Artikel.txt" ) and the url to this file ( < cm:URL value="http://cmwin01.ebusiness.local:9080/icmrm/ICMResourceManager/A10 ...) in string Variables using Java. I read several articles on how to do this ( Can't process SOAP response , How to do the Parsing of SOAP Response ) but without success. Here is what I tried: 我想获取文件名( ICCFileName =“ Golem_Artikel.txt” )和此文件的网址(< cm:URL value =“ http://cmwin01.ebusiness.local:9080 / icmrm / ICMResourceManager / A10 ... )(使用Java编写的字符串变量)中,我读了几篇有关如何执行此操作的文章( 无法处理SOAP响应如何进行SOAP响应的解析 ),但没有成功,这是我尝试的方法:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

// Clean response xml document
responseDocumentBody.normalizeDocument();
// Get result node
NodeList resultList = responseDocumentBody.getElementsByTagName("ICCSPArchivSuche");
Element resultElement = (Element) resultList.item(0);
String XMLData = resultElement.getTextContent();

// Check for empty result
if ("Data Not Found".equalsIgnoreCase(XMLData))
    return null;


DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource inputSource = new InputSource();
inputSource.setCharacterStream(new StringReader(XMLData));
Document doc = documentBuilder.parse(inputSource);
Node node = doc.getDocumentElement();
String result =  doc.getNodeType();


return result;

From Bonita, I only get responseDocumentBody or responseDocumentEnvelope (org.w3c.dom.Document) as webservice response. 从Bonita,我仅获得responseDocumentBody或responseDocumentEnvelope(org.w3c.dom.Document)作为Web服务响应。 Therefore, I need to navigate from the SOAP Body to my variables. 因此,我需要从SOAP正文导航到我的变量。 I would be pleased if someone could help. 如果有人可以帮我,我会很高兴。

Best regards 最好的祝福

If you do a lot of work with this, I would definitively recommend using JAXB as MGoron suggests. 如果您为此做了大量工作,那么我绝对会建议按照MGoron的建议使用JAXB。 If this is a one shot excersize, XPATH could also work well. 如果这只是一杆大事,那么XPATH也可以很好地工作。

    /*
     * Must use a namespace aware factory
     */
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc = dbf.newDocumentBuilder().parse(...);


    /*
     * Create an XPath object
     */
    XPath p = XPathFactory.newInstance().newXPath();

    /*
     * Must use a namespace context
     */
    p.setNamespaceContext(new NamespaceContext() {

        public Iterator getPrefixes(String namespaceURI) {
            return null;
        }

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

        public String getNamespaceURI(String prefix) {
            if (prefix.equals("ns1"))
                return "http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema";
            if (prefix.equals("cm"))
                return "http://www.ibm.com/xmlns/db2/cm/api/1.0/schema";
            return null;
        }
    });

    /*
     * Find the ICCSFileName attribute
     */
    Node iccsFileName = (Node) p.evaluate("//ns1:ICCSPArchivSuche/@ICCFileName", doc, XPathConstants.NODE);
    System.out.println(iccsFileName.getNodeValue());

    /*
     * Find the URL
     */
    Node url = (Node) p.evaluate("//ns1:ICCSPArchivSuche/cm:resourceObject/cm:URL/@value", doc, XPathConstants.NODE);
    System.out.println(url.getNodeValue());
  1. get RunQueryReply schema 获取RunQueryReply模式
  2. map xsd to java classes using jax-b 使用jax-b将xsd映射到java类
  3. unmarshall response string to jax-b class object 解组对jax-b类对象的响应字符串

Below is the code to do this in VTD-XML , it basically consists of 2 XPath queries, each returning one result... however the code is robust as it doesn't assume those queries will return non-empty result... 下面是在VTD-XML中执行此操作的代码,它基本上由2个XPath查询组成,每个查询都返回一个结果...但是该代码很健壮,因为它不假定这些查询将返回非空结果...

import com.ximpleware.*;

public class parseSOAP {
    public static void main(String[] s) throws VTDException, Exception{
        VTDGen vg = new VTDGen();
        vg.selectLcDepth(5);// soap has deep nesting so set to 5 to speed up navigation
        if (!vg.parseFile("d:\\xml\\soap2.xml", true))
            return;
        VTDNav vn = vg.getNav();
        AutoPilot ap =new AutoPilot(vn);

        //declare name space for xpath
        ap.declareXPathNameSpace("ns", "http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema");
        ap.declareXPathNameSpace("ns1", "http://www.ibm.com/xmlns/db2/cm/beans/1.0/schema");
        ap.declareXPathNameSpace("cm", "http://www.ibm.com/xmlns/db2/cm/api/1.0/schema");
        ap.declareXPathNameSpace("soapenv", "http://www.w3.org/2003/05/soap-envelope");


        ap.selectXPath("/soapenv:Envelope/soapenv:Body/ns1:RunQueryReply/ns1:ResultSet/ns1:Item/ns1:ItemXML//ICCSPArchivSuche/@ICCFileName");
        int i=0;
        if ((i=ap.evalXPath())!=-1){
            System.out.println("file name ==>"+vn.toString(i+1));
        }

        ap.selectXPath("/soapenv:Envelope/soapenv:Body/ns1:RunQueryReply/ns1:ResultSet/ns1:Item/ns1:ItemXML//ICCSPArchivSuche/cm:resourceObject/cm:URL/@value");
        if ((i=ap.evalXPath())!=-1){
            System.out.println("file name ==>"+vn.toString(i+1));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM