Technical Articles
Custom JSON to XML Converter in CPI
Introduction
As we are working on SAP CPI project it is a common requirements to have a message transformation from JSON to XML in our integration flow.
And based on our experience we found that there are some limitations in the JSON2XML component of the SAP CPI.
Some JSON format cannot be converted to XML by the standard CPI component for the JSON2XML converter.
If you want read further about the current limitations you can check the bellow reference :
- SAP notes : 2478282
- As well as from the SAP help portal : https://help.sap.com/doc/bd0ff312719b460f87556fc14e93f67a/Cloud/en-US/3a02829ea84e4f7dac62bdd10d06b084.html
The case and the Alternate Solution
Ok now lets jump in into the sample case and how we are going to deal with it ๐
Here I will create two integration flow.
The first one is using the default/standard SAP CPI’s JSON to XML converter.
And the second one is using a simple groovy script + custom library(*.jar files) to do the same(JSON to XML conversion.
Here we go our first integration flow:
First Integration Flow
The above integration flow is a very simple one, it will receive a JSON format and do the conversion to XML using CPI’s standard JSON to XML converter.
We will use the following JSON payload to test our integration flow :
{
"severity": "medium",
"createdDate": "Wed Sep 30 08:42:43 UTC 2020",
"topic": "instance-xxx-outlookemail-events",
"action": "create",
"id": "xxx",
"message": {
"elementKey": "outlookemail",
"accountId": 99999,
"eventId": "eventId",
"companyId": 66666,
"instanceId": 777777,
"instance_id": 777777,
"instanceName": "test-mail",
"instanceTags": [
"soltius-mail"
],
"raw": {
"eventHeaders": {
"id": "777777",
"encodedid": "NTkwMzAw",
"Raw-Element-Key": "outlookemail"
},
"pollDate": 1601455361934,
"messages": [
{
"ChangeKey": "CQAAABYAAADFfXRs5qJyQJRUntt2T2ZWAAD7AKgT",
"ConversationId": "AAQkADY4ZmFkZDEwLTBlMzctNGViMy05ZDc3LTQ4NWU2MTdlOTliMgAQAAXvfXGAyEHBgsssBzbAq18=",
"IsRead": false,
"ReceivedDateTime": "2020-09-30T08:38:07Z",
"Importance": "Normal",
"@odata.id": "odata.id",
"CcRecipients": [
{
"EmailAddress": {
"Address": "testcc1@test.com",
"Name": "testcc1"
}
},
{
"EmailAddress": {
"Address": "testcc2@test.com",
"Name": "testcc2"
}
}
],
"Body": {
"ContentType": "HTML",
"Content": "<html><head></head><body><div class=\"WordSection1\">Dear all</div></body></html>"
},
"ConversationIndex": "ConversationIndex",
"BodyPreview": "Dear all,\r\n\r\nFor your information",
"IsDraft": false,
"InferenceClassification": "Focused",
"LastModifiedDateTime": "2020-09-30T08:38:09Z",
"HasAttachments": true,
"ToRecipients": [
{
"EmailAddress": {
"Address": "rcvto1@test.com",
"Name": "rcvto1"
}
},
{
"EmailAddress": {
"Address": "rcvto2@test.com",
"Name": "rcvto2"
}
}
],
"@odata.etag": "W/\"CQAAABYAAA\"",
"SentDateTime": "2020-09-30T08:38:03Z",
"From": {
"EmailAddress": {
"Address": "sender@test.com",
"Name": "sender"
}
},
"Flag": {
"FlagStatus": "NotFlagged"
},
"ParentFolderId": "ParentFolderId",
"Subject": "Subject",
"WebLink": "WebLin",
"Sender": {
"EmailAddress": {
"Address": "sender@test.com",
"Name": "Sender"
}
},
"IsDeliveryReceiptRequested": false,
"InternetMessageId": "InternetMessageId",
"Id": "AAMkADY4Z",
"IsReadReceiptRequested": false,
"CreatedDateTime": "2020-09-30T08:38:06Z"
}
],
"objectType": "messages"
},
"userId": 99999,
"events": [
{
"elementKey": "outlookemail",
"pollDate": "2020-09-30T08:42:41Z",
"eventType": "UPDATED",
"hubKey": "general",
"objectId": "objectId",
"objectType": "messages"
}
]
},
"user": "notifications@cloud-elements.com"
}
In order to test our first integration flow, we use Postman and the above JSON as theย payload:
From above screen capture we can see that we got an error in our first integration flow.
So for the next step we will go to the message monitoring of our CPI and we can see the detailed error as follows :
As we can see from the above error the standard JSON to XML converter is unable to do the conversion of our JSON payload to the XML format
As a CPI developer one of our favorite feature of the CPI is we are able to write a groovy script ๐
We also able to use/upload custom library (*.jar files) in the resource tab of our integration flow.
As we are trying to overcome the issue from our first IFlow.
We create our second IFlow as shown below:
Second Integration Flow
From the above IFlow we can see that we will be using a groovy script to perform the JSON to XML conversion.
The groovy script snippet is as follows:
import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.json.JsonOutput;
import groovy.json.JsonSlurper;
import groovy.json.JsonBuilder;
import java.text.SimpleDateFormat;
import java.sql.Timestamp;
import net.sf.json.JSON
import net.sf.json.JSONSerializer
import net.sf.json.xml.XMLSerializer
def Message processData(Message message) {
String payload = message.getBody(java.lang.String)
def jsonSlurper = new JsonSlurper();
def object = jsonSlurper.parseText(payload.toString())
JSON json = JSONSerializer.toJSON( payload )
XMLSerializer xmlSerializer = new XMLSerializer()
xmlSerializer.setTypeHintsCompatibility( false )
xmlSerializer.setTypeHintsEnabled( false )
String xml = xmlSerializer.write( json )
message.setBody(xml);
return message;
}
As we can see from the above groovy script we will need several custom libraries for the:
import net.sf.json.*
The library(*.jar files) can be downloaded in the following source :
https://sourceforge.net/projects/json-lib/
After downloading the custom library.
We need to upload the jar files, in the following section of our Integration Flow:
Finally let’s test our second integration flow using the same JSON format via postman :
From the above image we can see that the second Integration Flow works well with the same JSON payload and able to convert the JSON payload into XML format as we expected.
Conclusion and call to action
From this post we understand that the CPI’s standard JSON to XML converter has some limitation.
And as(one of) the alternate solution we can use the groovy script and the custom libraries to do the JSON to XML Conversion.
Please feel free to share n the comment section, if you found the same issue related to the JSON to XML conversion and how you solve it.
We will be more than happy to discuss about ๐
Hi Hari
It would be useful to show what exactly in your input JSON payload that is causing the error/hitting a limitation.
Regards
Eng Swee
Hi Eng Swee,
Thank you for the input. But to be honest I'm not really know what's wrong in my json payload that causing the error ๐
So I just trying to write the script and it can convert my payload.
If someone can help me identify what's wrong with my json, payload it will be nice.
So we can take a note when we should looking for workaround or using the standard json to xml converter from SAP CPI.
Since the drawback of using my solution above is the IFlow size is getting bigger when we download it.
Cheer,
Hari
Eng Swee Yeoh I just tested it out of curiosity. The error of CPI's converter is "Trying to write an attribute when there is no open start element". After some trial'n'error it seems like that the standard converter doesn't handle the JSON because of the two JSON properties named "@odata.id" and "@odata.etag".ย
Hari Cahyadi Windyadi if you remove the @ chars from the properties (e.g. via Script), you can use the official JSON to XML converter.
Nice one, Raffael. You are always one that is up for a challenge ๐
Hi Raffael,
Thank you so much for your curiosity and taking your time to check my JSON payload.
Well noted.
Later we can write a small script to remove the wild characters and pass it to the official JSON to XML converter.
Happy weekend ๐
Hi Hari Cahyadi Windyadi ,
As suggested by Raffael Herrmann remove special characters and before using JSON to XML converter use Content modifier in below format, it should work now without script: -
{"root":
${in.body}
}
Regards,
Rashmi Joshi
Hi Rashmi Joshi,
Thanks for your advise.
At the time being I just left the payload as it is since it was sent from open connector when an event is triggered. I will consider your to use it in my next project so we can use the official converter โบ
Best regards,
Hari Cahyadi
Hi ,
I have downloaded from the link given and I see only one file with name "json-lib-2.4-jdk15.jar"
Could you let me know how to get all the other files you uploaded(I see around 7 Jars in your snapshot)
Thanks,
Dinesh
@ Dinesh M,
You can download the required JAR files for JSON to XML conversion from here
Thanks,
Akshay Bakliwal
Hi Hari Cahyadi Windyadi i downloaded the jar files and try to executed for my JSON structure.
Thanks a lot. It works fine ๐
Cรกtia
Hello,
ย
In my scenario I have a Request/Reply that gets a info from HTTP connection (it is one value only).
ย
I should get this value and send it to S/4.
ย
Is this case should I use the groovy script to convert the JSON to XML and pass it to XI connection?
ย
Att.,
Vinicius
Hello Hari and fellow experts,
I tried this method with a custom groovy to convert from JSON to XML for a response to my ERP but the ERP can't seem to parse the message in any case. Behaves the same with the standard as well as the script. Any recommendations?
Thank you!
hola, como puedo quitar en mi caso [ ] ya que los tengo al inicio y final del JSON y por eso no me deja convertirlo