cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

SAP HCI XML to JSON Converter string to integer

0 Kudos
12,313

hi all,

the xml to json convertor converts all elements into String, if you need an Integer what is workaround?

Accepted Solutions (1)

Accepted Solutions (1)

Sriprasadsbhat
Active Contributor
0 Kudos

Hello Morten and Alexey,

I think we can raise a request to SAP to have this feature in near future road map by importing the XSD Schema while converting XML to JSON to make sure relevant data types are maintained in converted JSON if its possible instead of converting everything to String.

Regards,

Sriprasad Shivaram Bhat

Answers (5)

Answers (5)

Sriprasadsbhat
Active Contributor

Hello Alexy,

By seeing above code from Gayathri got motivation to write some code for your case:)

Please find the below which will do the same [ Performance wise its i guess bit slower since you are parsing each and every element ]

JSON Input:

{
    "EmployeeData": {
        "Record": [{
                "PersonID": "P11",
                "UserID": "31",
                "EmployementID": "E221"
            }, {
                "PersonID": "P12",
                "UserID": "32",
                "EmployementID": "E222"
            }, {
                "PersonID": "P13",
                "UserID": "33",
                "EmployementID": "E223"
            }
        ]
    }
}

Code:

import com.sap.gateway.ip.core.customdev.util.Message;
import java.util.HashMap;
import groovy.json.*
def Message processData(Message message) {
    
    //Body 
    def body = message.getBody(String.class);
    
    def jsonSlurper = new JsonSlurper()
    def list = jsonSlurper.parseText(body)
    
    list.EmployeeData.Record.each{
        it.PersonID.toString()
        it.UserID=Integer.parseInt(it.get("UserID").toString());
        it.EmployementID.toString()
        }
    def jsonOP = JsonOutput.toJson(list)

    message.setBody(jsonOP)
    return message;
}

JSON OUTPUT:

{
    "EmployeeData": {
        "Record": [{
                "PersonID": "P11",
                "UserID": 31,
                "EmployementID": "E221"
            }, {
                "PersonID": "P12",
                "UserID": 32,
                "EmployementID": "E222"
            }, {
                "PersonID": "P13",
                "UserID": 33,
                "EmployementID": "E223"
            }
        ]
    }
}

Regards,

Sriprasad Shivaram Bhat

former_member757555
Discoverer
0 Kudos

Hi sriprasad.shivarambhat ,

A follow up question, I have a requirement where i do not have the same fields in each element,

For Example

{
    "EmployeeData": {
        "Record": [{
                "PersonID": "P11",
                "UserID": "31",
                "EmployementID": "E221"
            }, {
                "PersonID": "P12",
                "UserID": "32",
                "EmployementID": "E222"
            }, {
                "PersonID": "P13",
                "UserID": "33",
                "min_Value": "45"
"max_value": "50"
            }
        ]
    }
}
I only have to convert only min_Value and Max_Value fields which is not available in each record. In this case yuor script is giving error.Any Suggestions?
gayathri_narayana
Product and Topic Expert
Product and Topic Expert

Hi Alexey,

You could achieve this transformation using a groovy script. You could use groovy json facilities from http://groovy-lang.org/json.html .

For example if you would like to transform between

Source Message

<ns0:SourceMessage xmlns:ns0="http://source">

<ns0:Text>abcd</ns0:Text>

<ns0:List>

<ns0:Value id='001'>value_001</ns0:Value>

<ns0:Value id='003'>value_003</ns0:Value>

<ns0:Value id='002'>value_002</ns0:Value>

<ns0:Value id='004' ignore='yes'>value_004</ns0:Value>

</ns0:List>

</ns0:SourceMessage>

Target Message

<?xml version="1.0" encoding="UTF-8"?><ns1:TargetMessage xmlns:ns1="http://target">

<ns1:TEXT>abcd</ns1:TEXT>

<ns1:TIMESTAMP>2016-04-04T13:36:07</ns1:TIMESTAMP>

<ns1:UUID>a4264da0-dfe1-47c5-9bf0-02e09684cea4</ns1:UUID>

<ns1:LIST>

<ns1:VALUE>

<ns1:ID>001</ns1:ID>

<ns1:TEXT>value_001</ns1:TEXT>

</ns1:VALUE>

<ns1:VALUE>

<ns1:ID>002</ns1:ID>

<ns1:TEXT>value_002</ns1:TEXT>

</ns1:VALUE>

<ns1:VALUE>

<ns1:ID>003</ns1:ID>

<ns1:TEXT>value_003</ns1:TEXT>

</ns1:VALUE>

</ns1:LIST>

</ns1:TargetMessage>

The above example in this blog uses XmlParser. Alternatively you can use XmlSlurper which can have some performance advantages over XmlParser. Check groovy documentation for more details on XmlParser and XmlSlurper.

Groovy Documentation: http://groovy-lang.org/processing-xml.html

Groovy script:

import com.sap.gateway.ip.core.customdev.util.Message;

import java.util.HashMap;

import groovy.xml.*;

import java.util.*;

import java.text.SimpleDateFormat;

def Message processData(Message message) {

//Body

def body = message.getBody(String.class);

//def body = getSourceMessage();

def result = map(body);

message.setBody(result);

return message;

}

def String map(String message) {

def ns0 = new groovy.xml.Namespace("http://source",'ns0');

def ns1 = new groovy.xml.Namespace("http://target",'ns1');

def SourceMessage = new XmlParser().parseText(message);

def TargetMessage = new XmlParser().parseText(getTargetMessageTemplate());

//Generating Dates, UUIDs, etc...

final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

final String utcTime = sdf.format(new Date());

TargetMessage[ns1.TIMESTAMP][0].value = utcTime;

TargetMessage[ns1.UUID][0].value = java.util.UUID.randomUUID();

TargetMessage[ns1.TEXT][0].value = SourceMessage[ns0.Text][0].text();;

SourceMessage[ns0.List][ns0.Value].each {

def LocatedLine = new XmlParser().parseText(getTargetMessageListEntryTemplate());

LocatedLine[ns1.TEXT][0].value = it.text();

def ignore = it["@ignore"];

if (!"yes".equals(ignore)) {

LocatedLine[ns1.ID][0].value = it["@id"];

TargetMessage[ns1.LIST][0].append(LocatedLine);

}

}

def result = XmlUtil.serialize(TargetMessage);

return result;

}

///----------------------------------------------------------------------------------

/// XML Templates

def getSourceMessage() {

return'''

<ns0:SourceMessage xmlns:ns0="http://source">

<ns0:Text>abcd</ns0:Text>

<ns0:List>

<ns0:Value id='001'>value_001</ns0:Value>

<ns0:Value id='003'>value_003</ns0:Value>

<ns0:Value id='002'>value_002</ns0:Value>

<ns0:Value id='004' ignore='yes'>value_004</ns0:Value>

</ns0:List>

</ns0:SourceMessage>

'''.stripMargin();

}

def getTargetMessageTemplate() {

return'''

<ns1:TargetMessage xmlns:ns1="http://target">

<ns1:TEXT>abcd</ns1:TEXT>

<ns1:TIMESTAMP></ns1:TIMESTAMP>

<ns1:UUID></ns1:UUID>

<ns1:LIST>

</ns1:LIST>

</ns1:TargetMessage>

'''.stripMargin();

}

def getTargetMessageListEntryTemplate() {

return'''

<ns1:VALUE xmlns:ns1="http://target"><ns1:ID></ns1:ID><ns1:TEXT></ns1:TEXT></ns1:VALUE>

'''.stripMargin();

}

Hope this helps.

Regards,

Gayathri

MortenWittrock
SAP Mentor
SAP Mentor

Hi Alexey

I don't believe you are able to signal that kind of data type conversion. I would do the initial conversion using XML to JSON, and then perform any required cleanup in a subsequent script step.

Regards,

Morten

0 Kudos

Hi All,

You can refer to this blog and find the solution for above issue.

http://saphcidemo.blogspot.in/2017/10/json-code-for-conversion-of-string-to.html

0 Kudos

Hi all,

thanks everyone for responses. Finally i've come up with xslt transformation, the similar way as groovy scripting.

Totaly agree, that it should be included into standard transformation step.

akshayjain1991
Discoverer
0 Kudos
Hi ,
akshayjain1991
Discoverer
0 Kudos
Can you share the XSLT script