cancel
Showing results for 
Search instead for 
Did you mean: 

CPI: Parse data from SOAP xml response and forward to content modifier

ranjansb
Discoverer

I have two parts of this question.

Response data received from the SOAP request:

<ns:dataTransferResponsePart xmlns:ns="http://xxxxxxxxxxx.xxxx.xxx" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><responseData><formattedData><textData>Object ID
2019-01-09_R1JKES00000001
2019-04-22_R1JKTS00000040
</textData></formattedData></responseData></ns:dataTransferResponsePart>

The use case is to fetch the text content from the above response data tab of <textData>

Part 1:

One is to parse data from a SOAP based XML response and content from specific tag from the response.

I tried with multiple ways but that was snot successful. I tried creating Exchange property in the content modifier to forward the data by Xpath as follows,

value is given as : /ns:dataTransferResponsePart/responseData/formattedData/textData

I have tried the /ns: namespace to specify in the Namespace Mapping, However this didn't allowed to add as this namespace is used for other source.

part 2:

After giving up on the above approach, I tried with groovy script to parse the xml content and fetch the data from the tag as follows:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.util.XmlSlurper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
def Message processData(Message message) {
    Logger log = LoggerFactory.getLogger(this.getClass());
    try {
        def body = message.getBody(java.lang.String) as String;
        def downloadResponse = new XmlSlurper().parseText(body);
        def download_data = downloadResponse.ns:dataTransferResponsePart.responseData.formattedData.textData.text();
        message.setData(download_data);
    } catch (Exception ex) {
       log.error("processData error",ex);
    }
    return message;
}

Any help on the parsing and setting the data to message in the body is much appriciated.

MortenWittrock
Active Contributor
0 Kudos

By the way, this is a really good question. You describe in detail what you've tried so far, and where you got stuck. Thank you for that!

Regards,

Morten

Accepted Solutions (1)

Accepted Solutions (1)

MortenWittrock
Active Contributor

Hi Smruti

Thankfully, you don't need a Groovy script to do this. You can solve it with the trusty old Content Modifier, which was also your first approach.

You can change the XPath expression to /*/responseData/formattedData/textData and accomplish what you want.

You don't need the namespace mapping in this case, but I'd like to clarify something nevertheless. If the URI in question is already mapped to a different prefix, just use that prefix. If the same prefix is mapped to a different URI, map your URI to a different prefix (e.g. ns1 or whatever) and use that prefix instead. The prefixes do not matter (as long as you use them consistently); the URIs do.

Regards,

Morten

ranjansb
Discoverer

Thanks Morten for the response. The solution works perfectly.

hsonnenahalli
Contributor
0 Kudos

Morten-

Hope all is well. I have a question regarding extracting specific fields from a SOAP XML response and send it as input to the next call.

Please find the screenshot below. I have to need to extract all the fields under LogOnResult and send it as an input to my next call in the iflow. This seems to be tricky and am not sure if am doing it correctly. I have used the validator tool and my XPATH expression *// ServiceId is returning the result for ServiceId. But when I try the same in CM of CPI it is not filling the body. Please will you able to take a look at let me know what am missing.

Support is much appreciated.

Regards

Hari Sonnenahalli

Answers (1)

Answers (1)

vvaree
Explorer
0 Kudos

Alternatively , you can perform //*[local-name()='responseData'] to ignore the namespace.

The “local-name()” function offers a very convenient way to blow past any namespace errors/weirdness in an XML response to allow you to quickly identify an XML element