2

I need some help/advice with JSON to XML conversion in Node js. I have a service that gets a JSON object in request body that needs to convert to XML. I am able to achieve this using node-xml2js for json inputs with maximum one level of nested objects. But, it gets way more complicated with nested objects having attribute values. Attributes should be identified first, prefixed with $ sign and enclosed in curly braces before parsing through xml2js to get correct xml. Is there a better way of doing this where this complicated layer of reformatting the json input can be simplified? xml2js can converts this:

{
    "Level1":{  "$":{   "attribute":"value" },
                "Level2": {"$":{"attribute1":"05/29/2020",
                            "attribute2":"10","attribute3":"Pizza"}}
}

to this:(which is correct):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
  <Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>

But actual json input is this:

{
    "Level1":{"attribute":"value",
              "Level2": {"attribute1":"05/29/2020",
                         "attribute2":"10","attribute3":"Pizza"} }
}

Expected same result:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
  <Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>

Please let me know if you have worked on similar requirements. Appreciate any help. Thank you.

2 Answers 2

4

This would be a way to change the object back to the format expected in the library, although it assumes that all non object keys are supposed to be attributes (is that a valid assumption for your application?)

function groupChildren(obj) {
  for(prop in obj) { // consider filtering for own properties (vs from prototype: for(prop of Object.keys(obj)) {
    if (typeof obj[prop] === 'object') {
      groupChildren(obj[prop]);
    } else {
      obj['$'] = obj['$'] || {};
      obj['$'][prop] = obj[prop];
      delete obj[prop];
    }
  }

  return obj;
}

and then used like so:

var xml2js = require('xml2js'); 
var obj = {
  Level1: {
    attribute: 'value',
    Level2: {
      attribute1: '05/29/2020',
      attribute2: '10',
      attribute3: 'Pizza'
    }
  }
};

var builder = new xml2js.Builder();
var xml = builder.buildObject(groupChildren(obj));

which prints out:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Level1 attribute="value">
  <Level2 attribute1="05/29/2020" attribute2="10" attribute3="Pizza"/>
</Level1>
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you Dave. It works perfectly for me as there are only attributes in my scenario so I am accepting this as the correct answer. However, i'd like to try to enhance it for elements as well at some point. Thanks again.
Add this to the first line of the for-in loop if (!Object.prototype.hasOwnProperty.call(obj, prop)) continue;
@Vitim.us added caveat about properties from prototype
-1

you can use this library :nashwaan/xml-js

Like This:

  let xmlJ=require('xml-js');
  let parseToJson=(xml)=>{
        return new Promise(resolve => {
              let convert;
         
              convert=xmlJ.xml2json(xml,{compact:true});
              resolve(convert);
    
   });
 };

1 Comment

user is requesting JSON to XML not XML to JSON

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.