Mercurial > eldonilo > blog
view xml2json.js @ 11:f4422eafb0f8
Make forms building actually working.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Wed, 02 Nov 2011 10:02:31 -0700 |
parents | eb5b6d3ab09b |
children |
line wrap: on
line source
/* 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)); }