arnaucube
arnaucube/tuitviewerPublic Self-hosted repository
tuitviewer/xml2json.js
xml2json.jsRaw
  1/*	This work is licensed under Creative Commons GNU LGPL License.
  2
  3	License: http://creativecommons.org/licenses/LGPL/2.1/
  4   Version: 0.9
  5	Author:  Stefan Goessner/2006
  6	Web:     http://goessner.net/
  7*/
  8function xml2json(xml, tab) {
  9   var X = {
 10      toObj: function(xml) {
 11         var o = {};
 12         if (xml.nodeType==1) {   // element node ..
 13            if (xml.attributes.length)   // element with attributes  ..
 14               for (var i=0; i<xml.attributes.length; i++)
 15                  o["@"+xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue||"").toString();
 16            if (xml.firstChild) { // element has child nodes ..
 17               var textChild=0, cdataChild=0, hasElementChild=false;
 18               for (var n=xml.firstChild; n; n=n.nextSibling) {
 19                  if (n.nodeType==1) hasElementChild = true;
 20                  else if (n.nodeType==3 && n.nodeValue.match(/[^ \f\n\r\t\v]/)) textChild++; // non-whitespace text
 21                  else if (n.nodeType==4) cdataChild++; // cdata section node
 22               }
 23               if (hasElementChild) {
 24                  if (textChild < 2 && cdataChild < 2) { // structured element with evtl. a single text or/and cdata node ..
 25                     X.removeWhite(xml);
 26                     for (var n=xml.firstChild; n; n=n.nextSibling) {
 27                        if (n.nodeType == 3)  // text node
 28                           o["#text"] = X.escape(n.nodeValue);
 29                        else if (n.nodeType == 4)  // cdata node
 30                           o["#cdata"] = X.escape(n.nodeValue);
 31                        else if (o[n.nodeName]) {  // multiple occurence of element ..
 32                           if (o[n.nodeName] instanceof Array)
 33                              o[n.nodeName][o[n.nodeName].length] = X.toObj(n);
 34                           else
 35                              o[n.nodeName] = [o[n.nodeName], X.toObj(n)];
 36                        }
 37                        else  // first occurence of element..
 38                           o[n.nodeName] = X.toObj(n);
 39                     }
 40                  }
 41                  else { // mixed content
 42                     if (!xml.attributes.length)
 43                        o = X.escape(X.innerXml(xml));
 44                     else
 45                        o["#text"] = X.escape(X.innerXml(xml));
 46                  }
 47               }
 48               else if (textChild) { // pure text
 49                  if (!xml.attributes.length)
 50                     o = X.escape(X.innerXml(xml));
 51                  else
 52                     o["#text"] = X.escape(X.innerXml(xml));
 53               }
 54               else if (cdataChild) { // cdata
 55                  if (cdataChild > 1)
 56                     o = X.escape(X.innerXml(xml));
 57                  else
 58                     for (var n=xml.firstChild; n; n=n.nextSibling)
 59                        o["#cdata"] = X.escape(n.nodeValue);
 60               }
 61            }
 62            if (!xml.attributes.length && !xml.firstChild) o = null;
 63         }
 64         else if (xml.nodeType==9) { // document.node
 65            o = X.toObj(xml.documentElement);
 66         }
 67         else
 68            alert("unhandled node type: " + xml.nodeType);
 69         return o;
 70      },
 71      toJson: function(o, name, ind) {
 72         var json = name ? ("\""+name+"\"") : "";
 73         if (o instanceof Array) {
 74            for (var i=0,n=o.length; i<n; i++)
 75               o[i] = X.toJson(o[i], "", ind+"\t");
 76            json += (name?":[":"[") + (o.length > 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]";
 77         }
 78         else if (o == null)
 79            json += (name&&":") + "null";
 80         else if (typeof(o) == "object") {
 81            var arr = [];
 82            for (var m in o)
 83               arr[arr.length] = X.toJson(o[m], m, ind+"\t");
 84            json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}";
 85         }
 86         else if (typeof(o) == "string")
 87            json += (name&&":") + "\"" + o.toString() + "\"";
 88         else
 89            json += (name&&":") + o.toString();
 90         return json;
 91      },
 92      innerXml: function(node) {
 93         var s = ""
 94         if ("innerHTML" in node)
 95            s = node.innerHTML;
 96         else {
 97            var asXml = function(n) {
 98               var s = "";
 99               if (n.nodeType == 1) {
100                  s += "<" + n.nodeName;
101                  for (var i=0; i<n.attributes.length;i++)
102                     s += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue||"").toString() + "\"";
103                  if (n.firstChild) {
104                     s += ">";
105                     for (var c=n.firstChild; c; c=c.nextSibling)
106                        s += asXml(c);
107                     s += "</"+n.nodeName+">";
108                  }
109                  else
110                     s += "/>";
111               }
112               else if (n.nodeType == 3)
113                  s += n.nodeValue;
114               else if (n.nodeType == 4)
115                  s += "<![CDATA[" + n.nodeValue + "]]>";
116               return s;
117            };
118            for (var c=node.firstChild; c; c=c.nextSibling)
119               s += asXml(c);
120         }
121         return s;
122      },
123      escape: function(txt) {
124         return txt.replace(/[\\]/g, "\\\\")
125                   .replace(/[\"]/g, '\\"')
126                   .replace(/[\n]/g, '\\n')
127                   .replace(/[\r]/g, '\\r');
128      },
129      removeWhite: function(e) {
130         e.normalize();
131         for (var n = e.firstChild; n; ) {
132            if (n.nodeType == 3) {  // text node
133               if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node
134                  var nxt = n.nextSibling;
135                  e.removeChild(n);
136                  n = nxt;
137               }
138               else
139                  n = n.nextSibling;
140            }
141            else if (n.nodeType == 1) {  // element node
142               X.removeWhite(n);
143               n = n.nextSibling;
144            }
145            else                      // any other node
146               n = n.nextSibling;
147         }
148         return e;
149      }
150   };
151   if (xml.nodeType == 9) // document node
152      xml = xml.documentElement;
153   var json = X.toJson(X.toObj(X.removeWhite(xml)), xml.nodeName, "\t");
154   return "{\n" + tab + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "\n}";
155}