free-jqgrid
Version:
grid as jQuery plugin - fork of jqGrid before licensing change
344 lines (333 loc) • 11.4 kB
JavaScript
/**
The below work is licensed under Creative Commons GNU LGPL License.
Original work:
License: http://creativecommons.org/licenses/LGPL/2.1/
Author: Stefan Goessner/2006
Web: http://goessner.net/
Modifications made:
Version: 0.9-p5
Description: Restructured code, JSLint validated (no strict whitespaces),
added handling of empty arrays, empty strings, and int/floats values.
Author: Michael Schøler/2008-01-29
Web: http://michael.hinnerup.net/blog/2008/01/26/converting-json-to-xml-and-xml-to-json/
Description: json2xml added support to convert functions as CDATA
so it will be easy to write characters that cause some problems when convert
Author: Tony Tomov
*/
/*global jQuery, alert, define, exports, module, require */
/*jslint browser: true, vars: true, regexp: true, white: true */
(function (global, factory) {
"use strict";
if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module.
//console.log("jsonxml AMD");
define([
"jquery"
], function ($) {
//console.log("jsonxml AMD: define callback");
return factory($, global);
});
} else if (typeof module === "object" && module.exports) {
// Node/CommonJS
//console.log("jsonxml CommonJS, typeof define=" + typeof define + ", define=" + define);
module.exports = function (root, $) {
//console.log("jsonxml CommonJS: in module.exports");
if (!root) {
root = window;
}
//console.log("jsonxml CommonJS: before require('jquery')");
if ($ === undefined) {
// require("jquery") returns a factory that requires window to
// build a jQuery instance, we normalize how we use modules
// that require this pattern but the window provided is a noop
// if it's defined (how jquery works)
$ = typeof window !== "undefined" ?
require("jquery") :
require("jquery")(root);
}
//console.log("jsonxml CommonJS: before factory");
return factory($, root);
};
} else {
// Browser globals
//console.log("jsonxml Browser: before factory");
factory(jQuery, global);
}
}(typeof window !== "undefined" ? window : this, function ($, window) {
"use strict";
// begin module jsonxml
var xmlJsonClass = {
// Param "xml": Element or document DOM node.
// Param "tab": Tab or indent string for pretty output formatting omit or use empty string "" to supress.
// Returns: JSON string
xml2json: function (xml, tab) {
if (xml.nodeType === 9) {
// document node
xml = xml.documentElement;
}
var nws = this.removeWhite(xml),
obj = this.toObj(nws),
json = this.toJson(obj, xml.nodeName, "\t");
return "{\n" + tab + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "\n}";
},
// Param "o": JavaScript object
// Param "tab": tab or indent string for pretty output formatting omit or use empty string "" to supress.
// Returns: XML string
json2xml: function (o, tab) {
var toXml = function (v, name, ind) {
var xml = "", i, n, sXml, hasChild, m;
if (v instanceof Array) {
if (v.length === 0) {
xml += ind + "<" + name + ">__EMPTY_ARRAY_</" + name + ">\n";
} else {
for (i = 0, n = v.length; i < n; i += 1) {
sXml = ind + toXml(v[i], name, ind + "\t") + "\n";
xml += sXml;
}
}
} else if (typeof v === "object") {
hasChild = false;
xml += ind + "<" + name;
for (m in v) {
if (v.hasOwnProperty(m)) {
if (m.charAt(0) === "@") {
xml += " " + m.substr(1) + "=\"" + v[m].toString() + "\"";
} else {
hasChild = true;
}
}
}
xml += hasChild ? ">" : "/>";
if (hasChild) {
for (m in v) {
if (v.hasOwnProperty(m)) {
if (m === "#text") {
xml += v[m];
} else if (m === "#cdata") {
xml += "<![CDATA[" + v[m] + "]]>";
} else if (m.charAt(0) !== "@") {
xml += toXml(v[m], m, ind + "\t");
}
}
}
xml += (xml.charAt(xml.length - 1) === "\n" ? ind : "") + "</" + name + ">";
}
} else if (typeof v === "function") {
xml += ind + "<" + name + ">" + "<![CDATA[" + v + "]]>" + "</" + name + ">";
} else {
if (v === undefined) {
v = "";
}
if (v.toString() === "\"\"" || v.toString().length === 0) {
xml += ind + "<" + name + ">__EMPTY_STRING_</" + name + ">";
} else {
xml += ind + "<" + name + ">" + v.toString() + "</" + name + ">";
}
}
return xml;
},
xml1 = "",
p;
for (p in o) {
if (o.hasOwnProperty(p)) {
xml1 += toXml(o[p], p, "");
}
}
return tab ? xml1.replace(/\t/g, tab) : xml1.replace(/\t|\n/g, "");
},
// Internal methods
toObj: function (xml) {
var o = {}, funcTest = /function/i, i, textChild = 0, cdataChild = 0, hasElementChild = false, n;
if (xml.nodeType === 1) {
// element node ..
if (xml.attributes.length) {
// element with attributes ..
for (i = 0; i < xml.attributes.length; i += 1) {
o["@" + xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue || "").toString();
}
}
if (xml.firstChild) {
// element has child nodes ..
for (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]/)) {
// non-whitespace text
textChild += 1;
} else if (n.nodeType === 4) {
// cdata section node
cdataChild += 1;
}
}
if (hasElementChild) {
if (textChild < 2 && cdataChild < 2) {
// structured element with evtl. a single text or/and cdata node ..
this.removeWhite(xml);
for (n = xml.firstChild; n; n = n.nextSibling) {
if (n.nodeType === 3) {
// text node
o["#text"] = this.escape(n.nodeValue);
} else if (n.nodeType === 4) {
// cdata node
if (funcTest.test(n.nodeValue)) {
o[n.nodeName] = [o[n.nodeName], n.nodeValue];
} else {
o["#cdata"] = this.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] = this.toObj(n);
} else {
o[n.nodeName] = [o[n.nodeName], this.toObj(n)];
}
} else {
// first occurence of element ..
o[n.nodeName] = this.toObj(n);
}
}
} else {
// mixed content
if (!xml.attributes.length) {
o = this.escape(this.innerXml(xml));
} else {
o["#text"] = this.escape(this.innerXml(xml));
}
}
} else if (textChild) {
// pure text
if (!xml.attributes.length) {
o = this.escape(this.innerXml(xml));
if (o === "__EMPTY_ARRAY_") {
o = "[]";
} else if (o === "__EMPTY_STRING_") {
o = "";
}
} else {
o["#text"] = this.escape(this.innerXml(xml));
}
} else if (cdataChild) {
// cdata
if (cdataChild > 1) {
o = this.escape(this.innerXml(xml));
} else {
for (n = xml.firstChild; n; n = n.nextSibling) {
if (funcTest.test(xml.firstChild.nodeValue)) {
o = xml.firstChild.nodeValue;
break;
}
o["#cdata"] = this.escape(n.nodeValue);
}
}
}
}
if (!xml.attributes.length && !xml.firstChild) {
o = null;
}
} else if (xml.nodeType === 9) {
// document.node
o = this.toObj(xml.documentElement);
} else {
($.jgrid != null && $.jgrid.defaults != null && $.isFunction($.jgrid.defaults.fatalError) ? $.jgrid.defaults.fatalError : alert)("unhandled node type: " + xml.nodeType);
}
return o;
},
toJson: function (o, name, ind, wellform) {
if (wellform === undefined) {
wellform = true;
}
var json = name ? ("\"" + name + "\"") : "", tab = "\t", newline = "\n", n, i, ar = [], arr = [], m;
if (!wellform) {
tab = "";
newline = "";
}
if (o === "[]") {
json += (name ? ":[]" : "[]");
} else if (o instanceof Array) {
for (i = 0, n = o.length; i < n; i += 1) {
ar[i] = this.toJson(o[i], "", ind + tab, wellform);
}
json += (name ? ":[" : "[") + (ar.length > 1 ? (newline + ind + tab + ar.join("," + newline + ind + tab) + newline + ind) : ar.join("")) + "]";
} else if (o === null) {
json += (name && ":") + "null";
} else if (typeof o === "object") {
for (m in o) {
if (o.hasOwnProperty(m)) {
arr[arr.length] = this.toJson(o[m], m, ind + tab, wellform);
}
}
json += (name ? ":{" : "{") + (arr.length > 1 ? (newline + ind + tab + arr.join("," + newline + ind + tab) + newline + ind) : arr.join("")) + "}";
} else if (typeof o === "string") {
json += (name && ":") + "\"" + o.replace(/\\/g, "\\\\").replace(/\"/g, '\\"') + "\"";
} else {
json += (name && ":") + o.toString();
}
return json;
},
innerXml: function (node) {
var s = "", child,
asXml = function (n) {
var str = "", i, c;
if (n.nodeType === 1) {
str += "<" + n.nodeName;
for (i = 0; i < n.attributes.length; i += 1) {
str += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue || "").toString() + "\"";
}
if (n.firstChild) {
str += ">";
for (c = n.firstChild; c; c = c.nextSibling) {
str += asXml(c);
}
str += "</" + n.nodeName + ">";
} else {
str += "/>";
}
} else if (n.nodeType === 3) {
str += n.nodeValue;
} else if (n.nodeType === 4) {
str += "<![CDATA[" + n.nodeValue + "]]>";
}
return str;
};
if (node.hasOwnProperty("innerHTML")) {
s = node.innerHTML;
} else {
for (child = node.firstChild; child; child = child.nextSibling) {
s += asXml(child);
}
}
return s;
},
escape: function (txt) {
return txt.replace(/[\\]/g, "\\\\").replace(/[\"]/g, '\\"').replace(/[\n]/g, "\\n").replace(/[\r]/g, "\\r");
},
removeWhite: function (e) {
e.normalize();
var n = e.firstChild, nxt;
while (n) {
if (n.nodeType === 3) {
// text node
if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) {
// pure whitespace text node
nxt = n.nextSibling;
e.removeChild(n);
n = nxt;
} else {
n = n.nextSibling;
}
} else if (n.nodeType === 1) {
// element node
this.removeWhite(n);
n = n.nextSibling;
} else {
// any other node
n = n.nextSibling;
}
}
return e;
}
};
window.xmlJsonClass = xmlJsonClass;
// end module jsonxml
return xmlJsonClass;
}));