Skip to Content
Technical Articles
Author's profile photo Hari Cahyadi Windyadi

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 :

  1. SAP notes : 2478282
  2. 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:

IFlow-1

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:

Error%20in%20Postman

 

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 :

Message%20Processing%20Log

 

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%20Integration%20Flow

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:

Custom%20Jar%20Files

 

 

Finally let’s test our second integration flow using the same JSON format via postman :

Postman%20Result

 

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 ๐Ÿ™‚

Assigned Tags

      13 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Eng Swee Yeoh
      Eng Swee Yeoh

      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

      Author's profile photo Hari Cahyadi Windyadi
      Hari Cahyadi Windyadi
      Blog Post Author

      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

      Author's profile photo Raffael Herrmann
      Raffael Herrmann

      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.

      Author's profile photo Eng Swee Yeoh
      Eng Swee Yeoh

      Nice one, Raffael. You are always one that is up for a challenge ๐Ÿ˜‰

      Author's profile photo Hari Cahyadi Windyadi
      Hari Cahyadi Windyadi
      Blog Post Author

      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 ๐Ÿ™‚

      Author's profile photo Rashmi Joshi
      Rashmi Joshi

      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

      Author's profile photo Hari Cahyadi Windyadi
      Hari Cahyadi Windyadi
      Blog Post Author

      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

      Author's profile photo Dinesh M
      Dinesh M

      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

      Author's profile photo Akshay Bakliwal
      Akshay Bakliwal

      @ Dinesh M,

      You can download the required JAR files for JSON to XML conversion from here

      Thanks,

      Akshay Bakliwal

      Author's profile photo Catia Silva
      Catia Silva

      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

      Author's profile photo Vinicius Souza
      Vinicius Souza

      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

      Author's profile photo Jiggs Roger Peter Lewis
      Jiggs Roger Peter Lewis

      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!

      Author's profile photo CPI Corona
      CPI Corona

      hola, como puedo quitar en mi caso [ ] ya que los tengo al inicio y final del JSON y por eso no me deja convertirlo