Created
September 21, 2016 23:25
-
-
Save dannyvassallo/f5d6c3897e46c1cf65c9542bc3a1e77a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This work is licensed under Creative Commons GNU LGPL License. | |
License: http://creativecommons.org/licenses/LGPL/2.1/ | |
Version: 0.9 | |
Author: Stefan Goessner/2006 | |
Web: http://goessner.net/ | |
*/ | |
function xml2json(xml, tab) { | |
var X = { | |
toObj: function(xml) { | |
var o = {}; | |
if (xml.nodeType==1) { // element node .. | |
if (xml.attributes.length) // element with attributes .. | |
for (var i=0; i<xml.attributes.length; i++) | |
o["@"+xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue||"").toString(); | |
if (xml.firstChild) { // element has child nodes .. | |
var textChild=0, cdataChild=0, hasElementChild=false; | |
for (var n=xml.firstChild; n; n=n.nextSibling) { | |
if (n.nodeType==1) hasElementChild = true; | |
else if (n.nodeType==3 && n.nodeValue.match(/[^ \f\n\r\t\v]/)) textChild++; // non-whitespace text | |
else if (n.nodeType==4) cdataChild++; // cdata section node | |
} | |
if (hasElementChild) { | |
if (textChild < 2 && cdataChild < 2) { // structured element with evtl. a single text or/and cdata node .. | |
X.removeWhite(xml); | |
for (var n=xml.firstChild; n; n=n.nextSibling) { | |
if (n.nodeType == 3) // text node | |
o["#text"] = X.escape(n.nodeValue); | |
else if (n.nodeType == 4) // cdata node | |
o["#cdata"] = X.escape(n.nodeValue); | |
else if (o[n.nodeName]) { // multiple occurence of element .. | |
if (o[n.nodeName] instanceof Array) | |
o[n.nodeName][o[n.nodeName].length] = X.toObj(n); | |
else | |
o[n.nodeName] = [o[n.nodeName], X.toObj(n)]; | |
} | |
else // first occurence of element.. | |
o[n.nodeName] = X.toObj(n); | |
} | |
} | |
else { // mixed content | |
if (!xml.attributes.length) | |
o = X.escape(X.innerXml(xml)); | |
else | |
o["#text"] = X.escape(X.innerXml(xml)); | |
} | |
} | |
else if (textChild) { // pure text | |
if (!xml.attributes.length) | |
o = X.escape(X.innerXml(xml)); | |
else | |
o["#text"] = X.escape(X.innerXml(xml)); | |
} | |
else if (cdataChild) { // cdata | |
if (cdataChild > 1) | |
o = X.escape(X.innerXml(xml)); | |
else | |
for (var n=xml.firstChild; n; n=n.nextSibling) | |
o["#cdata"] = X.escape(n.nodeValue); | |
} | |
} | |
if (!xml.attributes.length && !xml.firstChild) o = null; | |
} | |
else if (xml.nodeType==9) { // document.node | |
o = X.toObj(xml.documentElement); | |
} | |
else | |
alert("unhandled node type: " + xml.nodeType); | |
return o; | |
}, | |
toJson: function(o, name, ind) { | |
var json = name ? ("\""+name+"\"") : ""; | |
if (o instanceof Array) { | |
for (var i=0,n=o.length; i<n; i++) | |
o[i] = X.toJson(o[i], "", ind+"\t"); | |
json += (name?":[":"[") + (o.length > 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]"; | |
} | |
else if (o == null) | |
json += (name&&":") + "null"; | |
else if (typeof(o) == "object") { | |
var arr = []; | |
for (var m in o) | |
arr[arr.length] = X.toJson(o[m], m, ind+"\t"); | |
json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}"; | |
} | |
else if (typeof(o) == "string") | |
json += (name&&":") + "\"" + o.toString() + "\""; | |
else | |
json += (name&&":") + o.toString(); | |
return json; | |
}, | |
innerXml: function(node) { | |
var s = "" | |
if ("innerHTML" in node) | |
s = node.innerHTML; | |
else { | |
var asXml = function(n) { | |
var s = ""; | |
if (n.nodeType == 1) { | |
s += "<" + n.nodeName; | |
for (var i=0; i<n.attributes.length;i++) | |
s += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue||"").toString() + "\""; | |
if (n.firstChild) { | |
s += ">"; | |
for (var c=n.firstChild; c; c=c.nextSibling) | |
s += asXml(c); | |
s += "</"+n.nodeName+">"; | |
} | |
else | |
s += "/>"; | |
} | |
else if (n.nodeType == 3) | |
s += n.nodeValue; | |
else if (n.nodeType == 4) | |
s += "<![CDATA[" + n.nodeValue + "]]>"; | |
return s; | |
}; | |
for (var c=node.firstChild; c; c=c.nextSibling) | |
s += asXml(c); | |
} | |
return s; | |
}, | |
escape: function(txt) { | |
return txt.replace(/[\\]/g, "\\\\") | |
.replace(/[\"]/g, '\\"') | |
.replace(/[\n]/g, '\\n') | |
.replace(/[\r]/g, '\\r'); | |
}, | |
removeWhite: function(e) { | |
e.normalize(); | |
for (var n = e.firstChild; n; ) { | |
if (n.nodeType == 3) { // text node | |
if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node | |
var nxt = n.nextSibling; | |
e.removeChild(n); | |
n = nxt; | |
} | |
else | |
n = n.nextSibling; | |
} | |
else if (n.nodeType == 1) { // element node | |
X.removeWhite(n); | |
n = n.nextSibling; | |
} | |
else // any other node | |
n = n.nextSibling; | |
} | |
return e; | |
} | |
}; | |
if (xml.nodeType == 9) // document node | |
xml = xml.documentElement; | |
var json = X.toJson(X.toObj(X.removeWhite(xml)), xml.nodeName, "\t"); | |
return "{\n" + tab + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "\n}"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment