comparison xml2json.js @ 0:f62b5c395a48

Initial commit.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sat, 04 Jun 2011 05:02:47 +0200
parents
children eb5b6d3ab09b
comparison
equal deleted inserted replaced
-1:000000000000 0:f62b5c395a48
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 */
8 var Element = function() {
9 this.getChildren = function(name, ns) {
10 var children = [];
11 var r = false;
12
13 for (var i in this) {
14 if (typeof this[i] !== 'object')
15 continue;
16
17 var child = this[i];
18 if((!name || i === name) &&
19 (!ns || child[0]['@xmlns'] === ns)) {
20 for (var j=0; j<child.length; j++)
21 children.push(child[j]);
22 r = true;
23 }
24 }
25
26 if (r)
27 return children;
28
29 return null;
30 };
31
32 this.getChild = function(name, ns) {
33 var children = this.getChildren(name, ns);
34 if (!children || children.length != 1)
35 return null;
36
37 return children[0];
38 };
39
40 this.getAttribute = function(name, ns) {
41 return this['@'+name]; // FIXME: namespace
42 };
43
44 this.getText = function() {
45 return this;
46 }
47 };
48
49 function xml2json(xml, tab) {
50 var X = {
51 toObj: function(xml, parentNS) {
52 var o = new Element();
53 if (xml.nodeType==1) { // element node ..
54 if (xml.attributes.length) // element with attributes ..
55 for (var i=0; i<xml.attributes.length; i++) {
56 o["@"+xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue||"").toString();
57 if (xml.attributes[i].nodeName === 'xmlns')
58 parentNS = xml.attributes[i].nodeValue;
59 }
60 if (!o['@xmlns'])
61 o['@xmlns'] = parentNS;
62 if (xml.firstChild) { // element has child nodes ..
63 var textChild=0, cdataChild=0, hasElementChild=false;
64 for (var n=xml.firstChild; n; n=n.nextSibling) {
65 if (n.nodeType==1) hasElementChild = true;
66 else if (n.nodeType==3 && n.nodeValue.match(/[\S]/)) textChild++; // non-whitespace text
67 else if (n.nodeType==4) cdataChild++; // cdata section node
68 }
69 if (hasElementChild) {
70 // structured element with evtl. a single text or/and cdata
71 // node ..
72 if (textChild < 2 && cdataChild < 2) {
73 X.removeWhite(xml);
74 for (var n=xml.firstChild; n; n=n.nextSibling)
75 if (n.nodeType == 3) // text node
76 o["#text"] = X.escape(n.nodeValue);
77 else if (n.nodeType == 4) // cdata node
78 o["#cdata"] = X.escape(n.nodeValue);
79 else {
80 if(!o[n.nodeName])
81 o[n.nodeName] = [X.toObj(n, parentNS)];
82 else
83 o[n.nodeName].push(X.toObj(n, parentNS));
84 }
85 }
86 else { // mixed content
87 if (!xml.attributes.length)
88 o = X.escape(X.innerXml(xml));
89 else
90 o["#text"] = X.escape(X.innerXml(xml));
91 }
92 }
93 else if (textChild) { // pure text
94 if (!xml.attributes.length)
95 o = X.escape(X.innerXml(xml)).replace(/\\\\/g, '\\');
96 else
97 o["#text"] = X.escape(X.innerXml(xml));
98 }
99 else if (cdataChild) { // cdata
100 if (cdataChild > 1)
101 o = X.escape(X.innerXml(xml));
102 else
103 for (var n=xml.firstChild; n; n=n.nextSibling)
104 o["#cdata"] = X.escape(n.nodeValue);
105 }
106 }
107
108 return (!xml.attributes.length && !xml.firstChild) ? null : o;
109 }
110
111 if (xml.nodeType==9) // document.node
112 return X.toObj(xml.documentElement);
113
114 throw("unhandled node type: " + xml.nodeType);
115 },
116 innerXml: function(node) {
117 var s = "";
118 if ("innerHTML" in node)
119 s = node.innerHTML;
120 else {
121 var asXml = function(n) {
122 var s = "";
123 if (n.nodeType == 1) {
124 s += "<" + n.nodeName;
125 for (var i=0; i<n.attributes.length;i++)
126 s += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue||"").toString() + "\"";
127 if (n.firstChild) {
128 s += ">";
129 for (var c=n.firstChild; c; c=c.nextSibling)
130 s += asXml(c);
131 s += "</"+n.nodeName+">";
132 }
133 else
134 s += "/>";
135 }
136 else if (n.nodeType == 3)
137 s += n.nodeValue;
138 else if (n.nodeType == 4)
139 s += "<![CDATA[" + n.nodeValue + "]]>";
140 return s;
141 };
142 for (var c=node.firstChild; c; c=c.nextSibling)
143 s += asXml(c);
144 }
145 return s;
146 },
147 escape: function(txt) {
148 return txt.replace(/[\\]/g, "\\\\")
149 .replace(/[\"]/g, '\\"')
150 .replace(/[\n]/g, '\\n')
151 .replace(/[\r]/g, '\\r');
152 },
153 removeWhite: function(e) {
154 e.normalize();
155 for (var n = e.firstChild; n; ) {
156 if (n.nodeType == 3) { // text node
157 if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node
158 var nxt = n.nextSibling;
159 e.removeChild(n);
160 n = nxt;
161 }
162 else
163 n = n.nextSibling;
164 }
165 else if (n.nodeType == 1) { // element node
166 X.removeWhite(n);
167 n = n.nextSibling;
168 }
169 else // any other node
170 n = n.nextSibling;
171 }
172 return e;
173 }
174 };
175 if (xml.nodeType == 9) // document node
176 xml = xml.documentElement;
177
178 //modified
179 return X.toObj(X.removeWhite(xml));
180 }