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}