| 1 |
/* |
| 2 |
### jQuery XML to JSON Plugin v1.3 - 2013-02-18 ### |
| 3 |
* http://www.fyneworks.com/ - diego@fyneworks.com |
| 4 |
* Licensed under http://en.wikipedia.org/wiki/MIT_License |
| 5 |
### |
| 6 |
Website: http://www.fyneworks.com/jquery/xml-to-json/ |
| 7 |
*//* |
| 8 |
# INSPIRED BY: http://www.terracoder.com/ |
| 9 |
AND: http://www.thomasfrank.se/xml_to_json.html |
| 10 |
AND: http://www.kawa.net/works/js/xml/objtree-e.html |
| 11 |
*//* |
| 12 |
This simple script converts XML (document of code) into a JSON object. It is the combination of 2 |
| 13 |
'xml to json' great parsers (see below) which allows for both 'simple' and 'extended' parsing modes. |
| 14 |
*/ |
| 15 |
// Avoid collisions |
| 16 |
;if(window.jQuery) (function($){ |
| 17 |
|
| 18 |
// Add function to jQuery namespace |
| 19 |
$.extend({ |
| 20 |
|
| 21 |
// converts xml documents and xml text to json object |
| 22 |
xml2json: function(xml, extended) { |
| 23 |
if(!xml) return {}; // quick fail |
| 24 |
|
| 25 |
//### PARSER LIBRARY |
| 26 |
// Core function |
| 27 |
function parseXML(node, simple){ |
| 28 |
if(!node) return null; |
| 29 |
var txt = '', obj = null, att = null; |
| 30 |
var nt = node.nodeType, nn = jsVar(node.localName || node.nodeName); |
| 31 |
var nv = node.text || node.nodeValue || ''; |
| 32 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,nt,nv.length+' bytes']); |
| 33 |
if(node.childNodes){ |
| 34 |
if(node.childNodes.length>0){ |
| 35 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'CHILDREN',node.childNodes]); |
| 36 |
$.each(node.childNodes, function(n,cn){ |
| 37 |
var cnt = cn.nodeType, cnn = jsVar(cn.localName || cn.nodeName); |
| 38 |
var cnv = cn.text || cn.nodeValue || ''; |
| 39 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>a',cnn,cnt,cnv]); |
| 40 |
if(cnt == 8){ |
| 41 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>b',cnn,'COMMENT (ignore)']); |
| 42 |
return; // ignore comment node |
| 43 |
} |
| 44 |
else if(cnt == 3 || cnt == 4 || !cnn){ |
| 45 |
// ignore white-space in between tags |
| 46 |
if(cnv.match(/^\s+$/)){ |
| 47 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>c',cnn,'WHITE-SPACE (ignore)']); |
| 48 |
return; |
| 49 |
}; |
| 50 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>d',cnn,'TEXT']); |
| 51 |
txt += cnv.replace(/^\s+/,'').replace(/\s+$/,''); |
| 52 |
// make sure we ditch trailing spaces from markup |
| 53 |
} |
| 54 |
else{ |
| 55 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>e',cnn,'OBJECT']); |
| 56 |
obj = obj || {}; |
| 57 |
if(obj[cnn]){ |
| 58 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>f',cnn,'ARRAY']); |
| 59 |
|
| 60 |
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child |
| 61 |
if(!obj[cnn].length) obj[cnn] = myArr(obj[cnn]); |
| 62 |
obj[cnn] = myArr(obj[cnn]); |
| 63 |
|
| 64 |
obj[cnn][ obj[cnn].length ] = parseXML(cn, true/* simple */); |
| 65 |
obj[cnn].length = obj[cnn].length; |
| 66 |
} |
| 67 |
else{ |
| 68 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'node>g',cnn,'dig deeper...']); |
| 69 |
obj[cnn] = parseXML(cn); |
| 70 |
}; |
| 71 |
}; |
| 72 |
}); |
| 73 |
};//node.childNodes.length>0 |
| 74 |
};//node.childNodes |
| 75 |
if(node.attributes){ |
| 76 |
if(node.attributes.length>0){ |
| 77 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'ATTRIBUTES',node.attributes]) |
| 78 |
att = {}; obj = obj || {}; |
| 79 |
$.each(node.attributes, function(a,at){ |
| 80 |
var atn = jsVar(at.name), atv = at.value; |
| 81 |
att[atn] = atv; |
| 82 |
if(obj[atn]){ |
| 83 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'ARRAY']); |
| 84 |
|
| 85 |
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child |
| 86 |
//if(!obj[atn].length) obj[atn] = myArr(obj[atn]);//[ obj[ atn ] ]; |
| 87 |
obj[cnn] = myArr(obj[cnn]); |
| 88 |
|
| 89 |
obj[atn][ obj[atn].length ] = atv; |
| 90 |
obj[atn].length = obj[atn].length; |
| 91 |
} |
| 92 |
else{ |
| 93 |
/*DBG*/ //if(window.console) console.log(['x2j',nn,'attr>',atn,'TEXT']); |
| 94 |
obj[atn] = atv; |
| 95 |
}; |
| 96 |
}); |
| 97 |
//obj['attributes'] = att; |
| 98 |
};//node.attributes.length>0 |
| 99 |
};//node.attributes |
| 100 |
if(obj){ |
| 101 |
obj = $.extend( (txt!='' ? new String(txt) : {}),/* {text:txt},*/ obj || {}/*, att || {}*/); |
| 102 |
//txt = (obj.text) ? (typeof(obj.text)=='object' ? obj.text : [obj.text || '']).concat([txt]) : txt; |
| 103 |
txt = (obj.text) ? ([obj.text || '']).concat([txt]) : txt; |
| 104 |
if(txt) obj.text = txt; |
| 105 |
txt = ''; |
| 106 |
}; |
| 107 |
var out = obj || txt; |
| 108 |
//console.log([extended, simple, out]); |
| 109 |
if(extended){ |
| 110 |
if(txt) out = {};//new String(out); |
| 111 |
txt = out.text || txt || ''; |
| 112 |
if(txt) out.text = txt; |
| 113 |
if(!simple) out = myArr(out); |
| 114 |
}; |
| 115 |
return out; |
| 116 |
};// parseXML |
| 117 |
// Core Function End |
| 118 |
// Utility functions |
| 119 |
var jsVar = function(s){ return String(s || '').replace(/-/g,"_"); }; |
| 120 |
|
| 121 |
// NEW isNum function: 01/09/2010 |
| 122 |
// Thanks to Emile Grau, GigaTecnologies S.L., www.gigatransfer.com, www.mygigamail.com |
| 123 |
function isNum(s){ |
| 124 |
// based on utility function isNum from xml2json plugin (http://www.fyneworks.com/ - diego@fyneworks.com) |
| 125 |
// few bugs corrected from original function : |
| 126 |
// - syntax error : regexp.test(string) instead of string.test(reg) |
| 127 |
// - regexp modified to accept comma as decimal mark (latin syntax : 25,24 ) |
| 128 |
// - regexp modified to reject if no number before decimal mark : ".7" is not accepted |
| 129 |
// - string is "trimmed", allowing to accept space at the beginning and end of string |
| 130 |
var regexp=/^((-)?([0-9]+)(([\.\,]{0,1})([0-9]+))?$)/ |
| 131 |
return (typeof s == "number") || regexp.test(String((s && typeof s == "string") ? jQuery.trim(s) : '')); |
| 132 |
}; |
| 133 |
// OLD isNum function: (for reference only) |
| 134 |
//var isNum = function(s){ return (typeof s == "number") || String((s && typeof s == "string") ? s : '').test(/^((-)?([0-9]*)((\.{0,1})([0-9]+))?$)/); }; |
| 135 |
|
| 136 |
var myArr = function(o){ |
| 137 |
|
| 138 |
// http://forum.jquery.com/topic/jquery-jquery-xml2json-problems-when-siblings-of-the-same-tagname-only-have-a-textnode-as-a-child |
| 139 |
//if(!o.length) o = [ o ]; o.length=o.length; |
| 140 |
if(!$.isArray(o)) o = [ o ]; o.length=o.length; |
| 141 |
|
| 142 |
// here is where you can attach additional functionality, such as searching and sorting... |
| 143 |
return o; |
| 144 |
}; |
| 145 |
// Utility functions End |
| 146 |
//### PARSER LIBRARY END |
| 147 |
|
| 148 |
// Convert plain text to xml |
| 149 |
if(typeof xml=='string') xml = $.text2xml(xml); |
| 150 |
|
| 151 |
// Quick fail if not xml (or if this is a node) |
| 152 |
if(!xml.nodeType) return; |
| 153 |
if(xml.nodeType == 3 || xml.nodeType == 4) return xml.nodeValue; |
| 154 |
|
| 155 |
// Find xml root node |
| 156 |
var root = (xml.nodeType == 9) ? xml.documentElement : xml; |
| 157 |
|
| 158 |
// Convert xml to json |
| 159 |
var out = parseXML(root, true /* simple */); |
| 160 |
|
| 161 |
// Clean-up memory |
| 162 |
xml = null; root = null; |
| 163 |
|
| 164 |
// Send output |
| 165 |
return out; |
| 166 |
}, |
| 167 |
|
| 168 |
// Convert text to XML DOM |
| 169 |
text2xml: function(str) { |
| 170 |
// NOTE: I'd like to use jQuery for this, but jQuery makes all tags uppercase |
| 171 |
//return $(xml)[0]; |
| 172 |
|
| 173 |
/* prior to jquery 1.9 */ |
| 174 |
/* |
| 175 |
var out; |
| 176 |
try{ |
| 177 |
var xml = ((!$.support.opacity && !$.support.style))?new ActiveXObject("Microsoft.XMLDOM"):new DOMParser(); |
| 178 |
xml.async = false; |
| 179 |
}catch(e){ throw new Error("XML Parser could not be instantiated") }; |
| 180 |
try{ |
| 181 |
if((!$.support.opacity && !$.support.style)) out = (xml.loadXML(str))?xml:false; |
| 182 |
else out = xml.parseFromString(str, "text/xml"); |
| 183 |
}catch(e){ throw new Error("Error parsing XML string") }; |
| 184 |
return out; |
| 185 |
*/ |
| 186 |
|
| 187 |
/* jquery 1.9+ */ |
| 188 |
return $.parseXML(str); |
| 189 |
} |
| 190 |
|
| 191 |
}); // extend $ |
| 192 |
|
| 193 |
})(jQuery); |
| 194 |
|