blob: b8053baaa12b1c260d14e8c24b997c945ac595b1 [file] [log] [blame]
Andrey Pavlov9b47f322020-04-05 22:31:40 +03001/*
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);