SDhwaj
SDhwaj

Reputation: 1

Extracting JSON content from CDATA in SOAP Response

I am working on SoapUI where I have a Soap request which takes input in Json String format and after the processing I get a Soap Response in XML with JSON format enclosed in CDATA.

I am trying to extract the data from Soap Response using the below code but I get error "Content is not allowed in prolog"

import com.eviware.soapui.support.XmlHolder
import net.sf.json.groovy.JsonSlurper
import groovy.xml.Namespace

respXmlHolder = new XmlHolder(messageExchange.getResponseContentAsXml())
respXmlHolder.declareNamespace("ns1","http://tempuri.org/")
CDATAXml = respXmlHolder.getNodeValue("//ns1:ReportResult")
log.info(CDATAXml)


def data = new XmlParser().parseText(CDATAXml).Rpt
log info "data.findAll{it.'Name'}.size()"

The Soap Response looks this way as shown below:

<ReportResponse xmlns="http://tempuri.org/">
     <ReportResult><![CDATA[{
  "Report": [
    {
      "Name": "ABC",
      "Number": "123",
      "Type": "XYZ",
      "Desc": "EFGH",
      "Group Name": "Name123",
      "Group Number": "123",
      "End Date": "12/30/2014",
      "Due Date": "04/15/2015",
      "Completion Date": null,
      "Status": "Status1",
      "Received Date": "",
      "Delivery Date": "",
      "Location": "",
      "Role": "",
     },
     {
      "Name": "EFG",
       "Number": "123",
      "Type": "XYZ",
      "Desc": "EFGH",
      "Group Name": "Name123",
      "Group Number": "123",
      "End Date": "12/30/2014",
      "Due Date": "04/15/2015",
      "Completion Date": null,
      "Status": "Status1",
      "Received Date": "",
      "Delivery Date": "",
      "Location": "",
      "Role": "Manager",
     }
    ]
} ]]></ReportResult>
  </ReportResponse>
   </s:Body>
</s:Envelope>

Please help me in this regard.

Upvotes: 0

Views: 3244

Answers (1)

albciff
albciff

Reputation: 18507

As @Rao note in the comments, you're using //ns1:Result as an XPath however this node doesn't exist in your response. Anyway as an alternative instead of use and XmlHolder, I purpose to use first XmlSlurper to parse the SOAP and get the CDATA node, and then JSonSlurper to parse the JSON contained in CDATA and get the desired values (in your case seems that you're looking for Name value attribute), see the below example:

import groovy.json.JsonSlurper

def soapResponse = '''<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
<ReportResponse xmlns="http://tempuri.org/">
     <ReportResult><![CDATA[{
  "Report": [
    {
      "Name": "ABC",
      "Number": "123",
      "Type": "XYZ",
      "Desc": "EFGH",
      "Group Name": "Name123",
      "Group Number": "123",
      "End Date": "12/30/2014",
      "Due Date": "04/15/2015",
      "Completion Date": null,
      "Status": "Status1",
      "Received Date": "",
      "Delivery Date": "",
      "Location": "",
      "Role": "",
     },
     {
      "Name": "EFG",
       "Number": "123",
      "Type": "XYZ",
      "Desc": "EFGH",
      "Group Name": "Name123",
      "Group Number": "123",
      "End Date": "12/30/2014",
      "Due Date": "04/15/2015",
      "Completion Date": null,
      "Status": "Status1",
      "Received Date": "",
      "Delivery Date": "",
      "Location": "",
      "Role": "Manager",
     }
    ]
} ]]></ReportResult>
  </ReportResponse>
   </s:Body>
</s:Envelope>'''

// parse the soap
def xml = new XmlSlurper().parseText(soapResponse)
// get cdata node
def reportCDATA = xml.'**'.findAll{ it.name() == 'ReportResult' }
def jsonTxt = reportCDATA.pop().toString()
// parse CDATA value as JSON
def json = new JsonSlurper().parseText(jsonTxt)
// get the Name attribute values
def names = json.Report.collect { it.Name }
names.each { log.info it }

If as you comment, instead of "Name" value of your JSON you want to get "Completion Date" you can do it as:

def completionDates = json.Report.collect { it."Completion Date"}

Or if looks more clear:

def completionDates = json.Report.collect { it[Completion Date] }

Take in account that in your sample the Report array contain two objects which both has null as value for "Completion Date". So using your JSON sample def completionDates will be [null, null].

Hope it helps,

Upvotes: 1

Related Questions