Joey Leblanc
Joey Leblanc

Reputation: 43

How to convert xml to JSON in suitescript 2.0

I have an XML response that i want to convert it to JSON, i'm currently usingg XPath

var responseNode = xml.XPath.select({
                                    node : xmlDocument,
                                    xpath : '//SOAP-ENV:Envelope'
                                });

and it is not very efficient because to extract data from one xml tag, i have to write a lot of extra code. I tried using external libs with suitescript but they didn't worked. Is there any better way to convert XML to JSON

Upvotes: 3

Views: 3008

Answers (3)

W.S.
W.S.

Reputation: 1515

create a helper.js file so the function can be shared across different scripts.

define(["N/xml"], function (xml) {

    function xmlToJson(text) {

        function xmlNodeToJson(xmlNode, obj) {
            var sibling = xmlNode;
            while (sibling) {
                if (sibling.nodeType == xml.NodeType.COMMENT_NODE) {
                    sibling = sibling.nextSibling;
                    continue;
                }
                if (sibling.nodeType == xml.NodeType.TEXT_NODE) {
                    if (!!sibling.nodeValue.replace(/[\n| ]/g, ''))
                        obj[sibling.nodeName] = sibling.nodeValue;
                    sibling = sibling.nextSibling;
                    continue;
                }
                var childObj = Object.create(null);
                if (!!sibling.hasAttributes()) {
                    Object.keys(sibling.attributes).forEach(function (key) {
                        childObj[key] = sibling.getAttribute({ name: key });
                    });
                }
                var value = xmlNodeToJson(sibling.firstChild, childObj);
                if ((sibling.nodeName in obj)) {
                    if (!Array.isArray(obj[sibling.nodeName])) {
                        obj[sibling.nodeName] = [obj[sibling.nodeName]];
                    }
                    obj[sibling.nodeName].push(value);
                } else {
                    obj[sibling.nodeName] = value;
                }
                sibling = sibling.nextSibling;
            }
            return obj;
        }

        var xmlDocument = xml.Parser.fromString({ text: text });
        return xmlNodeToJson(xmlDocument.firstChild, Object.create(null));
    }
    
    return {
        xmlToJson: xmlToJson
    }

});

import the helper file and use the xmlToJson function in your script.

define(['N/file', '/SuiteScripts/PATH_TO_HELPER_FILE/helper'], function(file, helper) {

    ...
    
    var string = file.load({ id: '/SuiteScripts/PATH_TO_FILE/filename.xml' }).getContents()
    var json_object = helper.xmlToJson(string);
    
    ...
    
})

Upvotes: 0

Charles Zhang
Charles Zhang

Reputation: 81

I have a project that needs to convert xml to json rencently, so I wrote the following function.

require(['N/xml'], function (xmlMod) {
//This function refer to https://davidwalsh.name/convert-xml-json
function xmlToJson(xmlNode) {
    // Create the return object
    var obj = Object.create(null);

    if (xmlNode.nodeType == xmlMod.NodeType.ELEMENT_NODE) { // element
        // do attributes
        if (xmlNode.hasAttributes()) {
            obj['@attributes'] = Object.create(null);
            for (var j in xmlNode.attributes) {
                if(xmlNode.hasAttribute({name : j})){
                    obj['@attributes'][j] = xmlNode.getAttribute({
                        name : j
                    });
                }
            }
        }
    } else if (xmlNode.nodeType == xmlMod.NodeType.TEXT_NODE) { // text
        obj = xmlNode.nodeValue;
    }

    // do children
    if (xmlNode.hasChildNodes()) {
        for (var i = 0, childLen = xmlNode.childNodes.length; i < childLen; i++) {
            var childItem = xmlNode.childNodes[i];
            var nodeName = childItem.nodeName;
            if (nodeName in obj) {
                if (!Array.isArray(obj[nodeName])) {
                    obj[nodeName] = [
                        obj[nodeName]
                    ];
                }
                obj[nodeName].push(xmlToJson(childItem));
            } else {
                obj[nodeName] = xmlToJson(childItem);
            }
        }
    }

    return obj;
};

var str = '<?xml version="1.0"?><ALEXA VER="0.9" URL="davidwalsh.name/" HOME="0" AID="="><SD TITLE="A" FLAGS="" HOST="davidwalsh.name"><TITLE TEXT="David Walsh Blog :: PHP, MySQL, CSS, Javascript, MooTools, and Everything Else">Hello World</TITLE><LINKSIN NUM="1102">Netsuite</LINKSIN><SPEED TEXT="1421" PCT="51"/></SD><SD><POPULARITY URL="davidwalsh.name/" TEXT="7131"/><REACH RANK="5952"/><RANK DELTA="-1648"/></SD></ALEXA>';

var xmlObj = xmlMod.Parser.fromString({
    text: str
});
var jsonObj = xmlToJson(xmlObj.documentElement);

log.debug('jsonObj', jsonObj);
});

The cenvert function referred to David Walsh's function located at: https://davidwalsh.name/convert-xml-json I just revised it compatible with Netsuite. Hope it works for you.

Upvotes: 3

w3bguy
w3bguy

Reputation: 2250

Here's a sample function from my NetSuite environment. I did not write this,but it is currently working.

//*********** PARSE XML INTO JSON ***********

function nsXMLToJSON(node){
  var obj=nsXMLToJSONDirty(node);  
  var cleanObj=cleanObject(obj,true);
  return cleanObj;

  //*********** HELPER FUNCTIONS ***********

  function nsXMLToJSONDirty(node){
    var obj={};
    if(!'nodeType' in node){
      return obj;
    }

    if(node.nodeType==1 || node.nodeType=='ELEMENT_NODE'){
      if(Object.keys(node.attributes).length > 0){
        obj["@attributes"]={};
        for(var j in node.attributes){
          var attribute=node.attributes[j];
          if(attribute){
            obj["@attributes"][attribute.name]=attribute.value;
          }
        }
      }
    }else if(node.nodeType==3 || node.nodeType=='TEXT_NODE'){
      obj=node.nodeValue;
    }

    if(node.hasChildNodes()){
      var childNodes=node.childNodes;
      for(var k in childNodes){
        var item=childNodes[k];
        var nodeName=item.nodeName;
        if(typeof (obj[nodeName])=="undefined"){
          obj[nodeName]=nsXMLToJSONDirty(item); //run the function again
        }else{
          if(typeof (obj[nodeName].push)=="undefined"){
            var old=obj[nodeName];
            obj[nodeName]=[];
            obj[nodeName].push(old);
          }
          obj[nodeName].push(nsXMLToJSONDirty(item));
        }
      }
    }
    return obj;
  }

  function cleanObject(myobj,recurse){
    var myobjcopy=JSON.parse(JSON.stringify(myobj));
    for(var i in myobjcopy){
      if(recurse && typeof myobjcopy[i]==='object'){
        if(i=="#text"){
          delete myobjcopy[i];
        } else {
          //Check if it only contains a text object
          if(Object.keys(myobjcopy[i]).length==1){
            if(typeof myobjcopy[i]['#text'] != "undefined"){
              if(myobjcopy[i]['#text'] || myobjcopy[i]['#text']==0){
                myobjcopy[i]=myobjcopy[i]['#text'];
              }
            }
          }else{
            //Handle empty objects
            if(Object.keys(myobjcopy[i]).length==0){
              myobjcopy[i]=undefined;            
            }
          }
          if(myobjcopy[i]){
            myobjcopy[i]=cleanObject(myobjcopy[i],recurse);
          }
        }
      }
    }
    return myobjcopy;
  }
}

Upvotes: 2

Related Questions