cancel
Showing results for 
Search instead for 
Did you mean: 

Convert XML to JSON in SAP HANA XSJS

Former Member
0 Kudos

Hi Experts,

I have a requirement in SAP HANA XSJS file where I need to accept input from UI in XML  format and convert into JSON format.

I have used below code to convert my XML format to JSON

$.import('sap.hana.xs.lm.core', 'xml2json');

var xml2json = $.sap.hana.xs.lm.core.xml2json.xml2json;

var parser = new $.util.SAXParser();

var xmlString = ('<root><UserId>USER1</UserId> <supplier>123</supplier><Company>ABC</Company></root>');

parser.parse(xmlString);

var jsonobject = {};

jsonobject = xml2json.parse(xmlString); //Convert xml to json

object = jsonobject.root; //removed root object

//Stringy to convert

var json = JSON.stringify(object, function(key,value){

if(key == "parent"){

             return undefined;

          }

          if(key == "attrs"){

             return undefined;

          }

         return value;

        });

but output am getting from the above statements is

'{"UserId":{"$":"USER1"},"supplier":{"$":"123"},"Company":{"$":"ABC"}}'

I was expecting output in the below format

'{"UserId":"USER1","supplier":"123","Company":"ABC"}'

could you help me out with the solution to convert XML to JSON

And one more thing is based on user input I need to check JSON/XML format  is there any method in Javascript (SAP HANA XS) to check the input format.

Thanks,

Anu

Accepted Solutions (1)

Accepted Solutions (1)

pfefferf
Active Contributor
0 Kudos

Hello Anu,

the XML to JSON converter you used (which is a specific implementation for Lifecycle management requirements) adds the values of the xml to a "$" property. Therefore JSON.stringify produces the string as you get it. This behavior cannot be adjusted by options for the converter. If you wanna use the result you have to adjust it afterwards, but this is ugly from my point of view.

If your XML structure is fix as you described it, following snippet can be used to convert the XML to a JS object which can then be stringified (of course if there are changes in the structure it is easy to adjust the snippet for your needs).


// convert XML to JS Object

function xml2Object(xml){

  var parser = new $.util.SAXParser();

  var result = {};

  var lastPropertyName = '';

  parser.startElementHandler = function(name, attrs){

    lastPropertyName = name;

 

    if(name === 'root'){

        return;

    }

 

    result[name] = '';

  };

  parser.characterDataHandler = function(value){

      result[lastPropertyName] = value;

  };

  parser.parse(xml);

  return result;

}

// test

var result = xml2Object('<root><UserId>USER1</UserId><supplier>123</supplier><Company>ABC</Company></root>');

$.response.contentType="application/json";

$.response.setBody(JSON.stringify(result));

Your XML example is converted to following result with the snippet:

Regarding the validation I do not know any available "out of the box" functionality on XS which lets you validate any kind of XML structure. But with the SAXParser functionality it would also easy to write a validator for your requirement.

Regards,

Florian

Former Member
0 Kudos
Hi Florian,

Thanks for the reply

I dont have a fixed input:

My JSON input:

{

    "UserId": "USER1",

    "supplier": "123",

    "Company": "ABC",

    "filter": {

        "CODE1": null,

        "GROUP": [],

        "MGR": ["test", "abc"],

    },

    "mpn": []

}

Converted XML input

<root>

  <UserId>USER1</UserId>

  <supplier>123</supplier>

  <Company>ABC</Company>

  <filter>

    <CODE1/>

    <GROUP/>

    <MGR>test</MGR>

    <MGR>abc</MGR>

  </filter>

  <mpn/>

</root>

I want to convert my XML back to JSON in XSJS in this case I need the output

JSON Output should be

{

    "UserId": "USER1",

    "supplier": "123",

    "Company": "ABC",

    "filter": {

        "CODE1": null,

        "GROUP": [],

        "MGR": ["test", "abc"],

    },

    "mpn": []

}

and if there is no value it should be null.

Could you please help me out with this.

Thanks in advance

Thanks,

Anu

pfefferf
Active Contributor
0 Kudos

As said it can be implemented in an easy way. For instance like following:


function xml2Object(xml){

  var parser = new $.util.SAXParser();

  var result = {};

  var lastName = '';

  var lastSetting = null;

  var lastElement = null;

 

  var settings = {};

  settings.root = { consider: false, parent: null, type: 'property' };

  settings.UserId = { consider: true, parent: null, type: 'property' };

  settings.supplier = { consider: true, parent: null, type: 'property' };

  settings.Company = { consider: true, parent: null, type: 'property' };

  settings.filter = { consider: true, parent: null, type: 'object' };

  settings.CODE1 = { consider: true, parent: 'filter', type: 'property' };

  settings.GROUP = { consider: true, parent: 'filter', type: 'array' };

  settings.MGR = { consider: true, parent: 'filter', type: 'array' };

  settings.mpn = { consider: true, parent: null, type: 'array' };

  parser.startElementHandler = function(name, attrs){

    lastName = name;

   

    lastSetting = settings[lastName];

     

    if(!lastSetting || lastSetting.consider === false){

        return;

    }   

   

    var parentStructure = [];

    var tmpSetting = lastSetting;

    while(tmpSetting.parent !== null){

        parentStructure.push(tmpSetting.parent);

        tmpSetting = settings[tmpSetting.parent];

    }

   

    lastElement = result;

   

    while(parentStructure.length > 0){

        var child = parentStructure.pop();

        lastElement = lastElement[child];

    }

   

    switch(lastSetting.type){

        case 'property':

            lastElement[lastName] = null;

            break;

        case 'object':

            lastElement[lastName] = {};

            break;

        case 'array':

            if(!lastElement[lastName]){

              lastElement[lastName] = [];

            }

            break;

    }

   

  };

 

  parser.characterDataHandler = function(value){ 

     switch(lastSetting.type){

         case 'property':

             lastElement[lastName] = value;

             break;

         case 'array':

             lastElement[lastName].push(value);

    }

  };

  parser.parse(xml);

 

  return result;

}

var xmlInput = '<root>' +

                  '<UserId>USER1</UserId>' +

                  '<supplier>123</supplier>' +

                  '<Company>ABC</Company>' +

                  '<filter>' +

                     '<CODE1/>' +

                     '<GROUP/>' +

                     '<MGR>test</MGR>' +

                     '<MGR>abc</MGR>' +

                  '</filter>' +

                  '<mpn/>' +

               '</root>';

              

var res = xml2Object(xmlInput);

$.response.contentType="application/json";

$.response.setBody(JSON.stringify(res));

Result:

Regards,

Florian

Former Member
0 Kudos

Thank you soo much

Thanks,

Anu

Answers (0)