Skip to Content
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 :

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

5 Comments
You must be Logged on to comment or reply to a post.
    • 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.

        • 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 πŸ™‚