diff 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
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/xml2json.js
@@ -0,0 +1,180 @@
+/*	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/ 
+*/
+var Element = function() {
+	this.getChildren = function(name, ns) {
+		var children = [];
+		var r = false;
+
+		for (var i in this) {
+			if (typeof this[i] !== 'object')
+				continue;
+
+			var child = this[i];
+			if((!name || i === name) &&
+			   (!ns || child[0]['@xmlns'] === ns)) {
+				for (var j=0; j<child.length; j++)
+					children.push(child[j]);
+				r = true;
+			}
+		}
+
+		if (r)
+			return children;
+
+		return null;
+	};
+
+	this.getChild = function(name, ns) {
+		var children = this.getChildren(name, ns);
+		if (!children || children.length != 1)
+			return null;
+
+		return children[0];
+	};
+
+	this.getAttribute = function(name, ns) {
+		return this['@'+name]; // FIXME: namespace
+	};
+
+	this.getText = function() {
+		return this;
+	}
+};
+
+function xml2json(xml, tab) {
+  var X = {
+    toObj: function(xml, parentNS) {
+      var o = new Element();
+      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.attributes[i].nodeName === 'xmlns')
+	      parentNS = xml.attributes[i].nodeValue;
+	  }
+	  if (!o['@xmlns'])
+	    o['@xmlns'] = parentNS;
+          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(/[\S]/)) textChild++; // non-whitespace text
+              else if (n.nodeType==4) cdataChild++; // cdata section node
+            }
+            if (hasElementChild) {
+              // structured element with evtl. a single text or/and cdata
+              // node ..
+              if (textChild < 2 && cdataChild < 2) {
+                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])
+                      o[n.nodeName] = [X.toObj(n, parentNS)];
+                    else
+                      o[n.nodeName].push(X.toObj(n, parentNS));
+                  }
+              }
+              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)).replace(/\\\\/g, '\\');
+              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);
+            }
+          }
+
+          return (!xml.attributes.length && !xml.firstChild) ? null : o;
+        }
+
+        if (xml.nodeType==9)  // document.node
+          return X.toObj(xml.documentElement);
+
+        throw("unhandled node type: " + xml.nodeType);
+      },
+      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;
+
+   //modified
+   return X.toObj(X.removeWhite(xml));
+}