Thursday, June 16, 2011

XML to JSON and JSON to XML Conversion in Javascript

When we deal with today's highly ajax based web application developments, dealing with XMLs within your page might be a little bit tedious task. As all of us know, JavaScript doesn't have a proper way to deal with XMLs(although recent specs supports E4X, it hasn't implemented in all browsers). If we can convert the XML into a JSON format, then it will be a great relief for web developers.

Although there are many XML to JSON notations available, all of them tends to ignore xml namespaces, but Badgerfish. So, I thought of writing a JavaScript code which does the XML to JSON conversion and wise-versa. If you want to get the Javascript code for XML to JSON, then go though my blog post XML to BadgerFish Conversion in Javascript. In this post, I will give you the function which converts JSON back to it's original XML.

Using these xml2bf and bf2xml functions, you will get the most flexibility with XML in your web developments.
function bf2xml(json) {
    if (typeof json !== "object") return null;
    var cloneNS = function(ns) {
        var nns = {};
        for (var n in ns) {
            if (ns.hasOwnProperty(n)) {
                nns[n] = ns[n];
            }
        }
        return nns;
    };
    var processLeaf = function(lname, child, ns) {
        var body = "";
        if (child instanceof Array) {
            for (var i = 0; i < child.length; i++) {
                body += processLeaf(lname, child[i], cloneNS(ns));
            }
            return body;
        } else if (typeof child === "object") {
            var el = "<" + lname;
            var attributes = "";
            var text = "";
            if (child["@xmlns"]) {
                var xmlns = child["@xmlns"];
                for (var prefix in xmlns) {
                    if (xmlns.hasOwnProperty(prefix)) {
                        if (prefix === "$") {
                            if (ns[prefix] !== xmlns[prefix]) {
                                attributes += " " + "xmlns=\"" + xmlns[prefix] + "\"";
                                ns[prefix] = xmlns[prefix];
                            }
                        } else if (!ns[prefix] || (ns[prefix] !== xmlns[prefix])) {
                            attributes += " xmlns:" + prefix + "=\"" + xmlns[prefix] + "\"";
                            ns[prefix] = xmlns[prefix];
                        }
                    }
                }
            }
            for (var key in child) {
                if (child.hasOwnProperty(key) && key !== "@xmlns") {
                    var obj = child[key];
                    if (key === "$") {
                        text += obj;
                    } else if (key.indexOf("@") === 0) {
                        attributes += " " + key.substring(1) + "=\"" + obj + "\"";
                    } else {
                        body += processLeaf(key, obj, cloneNS(ns));
                    }
                }
            }
            body = text + body;
            return (body !== "") ? el + attributes + ">" + body + "</" + lname + ">" : el + attributes + "/>"
        }
    };
    for (var lname in json) {
        if (json.hasOwnProperty(lname) && lname.indexOf("@") == -1) {
            return processLeaf(lname, json[lname], {});
        }
    }
    return null;
}

7 comments:

  1. /*******************************************
    * Yariv de Botton ydb@yariv-debotton.com *
    * 2012 *
    *******************************************/

    /**
    * This recursive function takes object, like json object
    * and makes an xml out of it
    * @param o The object
    * @param doc An xml document, for creating xml nodes
    * @returns on object with the nodes
    */
    var objToXml = function(o,doc){
    var e = {}; // object to be returned

    // Iterating through the object
    for(var x in o)if(o.hasOwnProperty(x)){

    // Child nodes or the nodes themselves
    var childs = {};

    switch(typeof o[x]){

    // if the subobject is an object (or array) recurse
    case "object":{
    childs = objToXml(o[x],doc);
    }break;

    // if it is scalar, make a text node as the single element of childs
    default:{
    childs[x] = doc.createTextNode(o[x]);
    }break;
    }

    // assoiciative arrays will create nodes and append the childs in them
    // whereas arrays will just accumulate the nodes
    if(isNaN(x)){ // object (associative array)
    e[x] = doc.createElement(x); // create a node
    for(var c in childs)if(childs.hasOwnProperty(c)){
    e[x].appendChild(childs[c]); // append the node
    }
    }else{ // regular (numeric keys) array
    for(var c in childs)if(childs.hasOwnProperty(c)){
    e[x + "[" + c + "]"] = childs[c]; // just assign the node
    }
    }
    }
    return e;
    }

    var o = {'d':{"gt":"h",'tarnegol':['ku',{'ku':'karbolet'},'ri','ku'],"ba:ba":{"ta":"mar"}}};

    var res = objToXml(o,document.implementation.createDocument());

    ReplyDelete
  2. Hi,

    I am getting Json response in siebel and want to convert it to XML. i have tried with above code. but its not working. Please give the details to how to convert json to xml. Please send an email to ankamguru@gmail.com.

    Thanks in Adavance
    Regards,
    Guru
    ankamguru@gmail.com

    ReplyDelete
  3. Hi
    Here is an xml to json converter:
    http://coursesweb.net/javascript/convert-xml-json-javascript_s2
    It is a javascript object that returns json string, or object, directly from file or string with xml content.

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Most easiest way to convert json to xml Keyword/text

    ReplyDelete