Reputation: 43
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
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
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
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