Statistics
| Branch: | Tag: | Revision:

root / src / org / json / JSONML.java @ 4bf05cad

History | View | Annotate | Download (14.3 kB)

1 14ad7326 pastith
package org.json;
2 14ad7326 pastith
3 14ad7326 pastith
/*
4 14ad7326 pastith
Copyright (c) 2008 JSON.org
5 14ad7326 pastith

6 14ad7326 pastith
Permission is hereby granted, free of charge, to any person obtaining a copy
7 14ad7326 pastith
of this software and associated documentation files (the "Software"), to deal
8 14ad7326 pastith
in the Software without restriction, including without limitation the rights
9 14ad7326 pastith
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 14ad7326 pastith
copies of the Software, and to permit persons to whom the Software is
11 14ad7326 pastith
furnished to do so, subject to the following conditions:
12 14ad7326 pastith

13 14ad7326 pastith
The above copyright notice and this permission notice shall be included in all
14 14ad7326 pastith
copies or substantial portions of the Software.
15 14ad7326 pastith

16 14ad7326 pastith
The Software shall be used for Good, not Evil.
17 14ad7326 pastith

18 14ad7326 pastith
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 14ad7326 pastith
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 14ad7326 pastith
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 14ad7326 pastith
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 14ad7326 pastith
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 14ad7326 pastith
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 14ad7326 pastith
SOFTWARE.
25 14ad7326 pastith
*/
26 14ad7326 pastith
27 14ad7326 pastith
import java.util.Iterator;
28 14ad7326 pastith
29 14ad7326 pastith
30 14ad7326 pastith
/**
31 14ad7326 pastith
 * This provides static methods to convert an XML text into a JSONArray or 
32 14ad7326 pastith
 * JSONObject, and to covert a JSONArray or JSONObject into an XML text using 
33 14ad7326 pastith
 * the JsonML transform.
34 14ad7326 pastith
 * @author JSON.org
35 14ad7326 pastith
 * @version 2008-09-18
36 14ad7326 pastith
 */
37 14ad7326 pastith
public class JSONML {
38 14ad7326 pastith
                
39 14ad7326 pastith
    /**
40 14ad7326 pastith
     * Parse XML values and store them in a JSONArray.
41 14ad7326 pastith
     * @param x       The XMLTokener containing the source string.
42 14ad7326 pastith
     * @param arrayForm true if array form, false if object form.
43 14ad7326 pastith
     * @param ja      The JSONArray that is containing the current tag or null
44 14ad7326 pastith
     *     if we are at the outermost level.
45 14ad7326 pastith
     * @return A JSONArray if the value is the outermost tag, otherwise null.
46 14ad7326 pastith
     * @throws JSONException
47 14ad7326 pastith
     */
48 14ad7326 pastith
    private static Object parse(XMLTokener x, boolean arrayForm, 
49 14ad7326 pastith
                    JSONArray ja) throws JSONException {
50 14ad7326 pastith
        String     attribute;
51 14ad7326 pastith
        char       c;
52 14ad7326 pastith
        String           closeTag = null;
53 14ad7326 pastith
        int        i;
54 14ad7326 pastith
        JSONArray  newja = null;
55 14ad7326 pastith
        JSONObject newjo = null;
56 14ad7326 pastith
        Object     token;
57 14ad7326 pastith
        String           tagName = null;
58 14ad7326 pastith
        
59 14ad7326 pastith
// Test for and skip past these forms:
60 14ad7326 pastith
//      <!-- ... -->
61 14ad7326 pastith
//      <![  ... ]]>
62 14ad7326 pastith
//      <!   ...   >
63 14ad7326 pastith
//      <?   ...  ?>
64 14ad7326 pastith
        
65 14ad7326 pastith
        while (true) {
66 14ad7326 pastith
                token = x.nextContent();
67 14ad7326 pastith
                    if (token == XML.LT) {
68 14ad7326 pastith
                            token = x.nextToken();
69 14ad7326 pastith
                            if (token instanceof Character) {
70 14ad7326 pastith
                                if (token == XML.SLASH) {
71 14ad7326 pastith
72 14ad7326 pastith
// Close tag </
73 14ad7326 pastith
74 14ad7326 pastith
                                        token = x.nextToken();
75 14ad7326 pastith
                                        if (!(token instanceof String)) {
76 14ad7326 pastith
                                                throw new JSONException(
77 14ad7326 pastith
                                                                "Expected a closing name instead of '" + 
78 14ad7326 pastith
                                                                token + "'.");
79 14ad7326 pastith
                                        }
80 14ad7326 pastith
                                    if (x.nextToken() != XML.GT) {
81 14ad7326 pastith
                                        throw x.syntaxError("Misshaped close tag");
82 14ad7326 pastith
                                    }
83 14ad7326 pastith
                                    return token;
84 14ad7326 pastith
                                } else if (token == XML.BANG) {
85 14ad7326 pastith
                        
86 14ad7326 pastith
// <!
87 14ad7326 pastith
                
88 14ad7326 pastith
                                    c = x.next();
89 14ad7326 pastith
                                    if (c == '-') {
90 14ad7326 pastith
                                        if (x.next() == '-') {
91 14ad7326 pastith
                                            x.skipPast("-->");
92 14ad7326 pastith
                                        }
93 14ad7326 pastith
                                        x.back();
94 14ad7326 pastith
                                    } else if (c == '[') {
95 14ad7326 pastith
                                        token = x.nextToken();
96 14ad7326 pastith
                                        if (token.equals("CDATA") && x.next() == '[') {
97 14ad7326 pastith
                                                if (ja != null) {
98 14ad7326 pastith
                                                        ja.put(x.nextCDATA());
99 14ad7326 pastith
                                                }
100 14ad7326 pastith
                                        } else {
101 14ad7326 pastith
                                                throw x.syntaxError("Expected 'CDATA['");
102 14ad7326 pastith
                                        }
103 14ad7326 pastith
                                    } else {
104 14ad7326 pastith
                                            i = 1;
105 14ad7326 pastith
                                            do {
106 14ad7326 pastith
                                                token = x.nextMeta();
107 14ad7326 pastith
                                                if (token == null) {
108 14ad7326 pastith
                                                    throw x.syntaxError("Missing '>' after '<!'.");
109 14ad7326 pastith
                                                } else if (token == XML.LT) {
110 14ad7326 pastith
                                                    i += 1;
111 14ad7326 pastith
                                                } else if (token == XML.GT) {
112 14ad7326 pastith
                                                    i -= 1;
113 14ad7326 pastith
                                                }
114 14ad7326 pastith
                                            } while (i > 0);
115 14ad7326 pastith
                                    }
116 14ad7326 pastith
                                } else if (token == XML.QUEST) {
117 14ad7326 pastith
118 14ad7326 pastith
// <?
119 14ad7326 pastith
120 14ad7326 pastith
                                        x.skipPast("?>");
121 14ad7326 pastith
                                } else {
122 14ad7326 pastith
                                    throw x.syntaxError("Misshaped tag");
123 14ad7326 pastith
                                }
124 14ad7326 pastith
125 14ad7326 pastith
// Open tag <
126 14ad7326 pastith
127 14ad7326 pastith
                        } else {
128 14ad7326 pastith
                                if (!(token instanceof String)) {
129 14ad7326 pastith
                                    throw x.syntaxError("Bad tagName '" + token + "'.");                                        
130 14ad7326 pastith
                                }
131 14ad7326 pastith
                                tagName = (String)token;
132 14ad7326 pastith
                            newja = new JSONArray();                
133 14ad7326 pastith
                            newjo = new JSONObject();
134 14ad7326 pastith
                                if (arrayForm) {
135 14ad7326 pastith
                                    newja.put(tagName);
136 14ad7326 pastith
                                    if (ja != null) {
137 14ad7326 pastith
                                            ja.put(newja);
138 14ad7326 pastith
                                    }
139 14ad7326 pastith
                                } else {
140 14ad7326 pastith
                                        newjo.put("tagName", tagName);
141 14ad7326 pastith
                                        if (ja != null) {
142 14ad7326 pastith
                                            ja.put(newjo);
143 14ad7326 pastith
                                    }
144 14ad7326 pastith
                                }
145 14ad7326 pastith
                            token = null;
146 14ad7326 pastith
                            for (;;) {
147 14ad7326 pastith
                                if (token == null) {
148 14ad7326 pastith
                                    token = x.nextToken();
149 14ad7326 pastith
                                }
150 14ad7326 pastith
                                if (token == null) {
151 14ad7326 pastith
                                        throw x.syntaxError("Misshaped tag");
152 14ad7326 pastith
                                }
153 14ad7326 pastith
                                if (!(token instanceof String)) {
154 14ad7326 pastith
                                        break;
155 14ad7326 pastith
                                }
156 14ad7326 pastith
157 14ad7326 pastith
//                              attribute = value
158 14ad7326 pastith
159 14ad7326 pastith
                            attribute = (String)token;
160 14ad7326 pastith
                                        if (!arrayForm && (attribute == "tagName" || attribute == "childNode")) {
161 14ad7326 pastith
                            throw x.syntaxError("Reserved attribute.");                                                
162 14ad7326 pastith
                                        }
163 14ad7326 pastith
                            token = x.nextToken();
164 14ad7326 pastith
                            if (token == XML.EQ) {
165 14ad7326 pastith
                                token = x.nextToken();
166 14ad7326 pastith
                                if (!(token instanceof String)) {
167 14ad7326 pastith
                                    throw x.syntaxError("Missing value");
168 14ad7326 pastith
                                }
169 14ad7326 pastith
                                newjo.accumulate(attribute, JSONObject.stringToValue((String)token));
170 14ad7326 pastith
                                token = null;
171 14ad7326 pastith
                            } else {
172 14ad7326 pastith
                                    newjo.accumulate(attribute, "");
173 14ad7326 pastith
                            }
174 14ad7326 pastith
                            }
175 14ad7326 pastith
                    if (arrayForm && newjo.length() > 0) {
176 14ad7326 pastith
                            newja.put(newjo);
177 14ad7326 pastith
                    }
178 14ad7326 pastith
179 14ad7326 pastith
// Empty tag <.../>
180 14ad7326 pastith
181 14ad7326 pastith
                        if (token == XML.SLASH) {
182 14ad7326 pastith
                            if (x.nextToken() != XML.GT) {
183 14ad7326 pastith
                                throw x.syntaxError("Misshaped tag");
184 14ad7326 pastith
                            }
185 14ad7326 pastith
                            if (ja == null) {
186 14ad7326 pastith
                                    return arrayForm ? newja : newjo;
187 14ad7326 pastith
                            }
188 14ad7326 pastith
189 14ad7326 pastith
// Content, between <...> and </...>
190 14ad7326 pastith
191 14ad7326 pastith
                        } else {
192 14ad7326 pastith
                                if (token != XML.GT) {
193 14ad7326 pastith
                                        throw x.syntaxError("Misshaped tag");
194 14ad7326 pastith
                                }
195 14ad7326 pastith
                                closeTag = (String)parse(x, arrayForm, newja);
196 14ad7326 pastith
                                if (closeTag != null) {
197 14ad7326 pastith
                                        if (!closeTag.equals(tagName)) {
198 14ad7326 pastith
                                                throw x.syntaxError("Mismatched '" + tagName + 
199 14ad7326 pastith
                                                                "' and '" + closeTag + "'");
200 14ad7326 pastith
                                                }
201 14ad7326 pastith
                                        tagName = null;
202 14ad7326 pastith
                                            if (!arrayForm && newja.length() > 0) {
203 14ad7326 pastith
                                                    newjo.put("childNodes", newja);
204 14ad7326 pastith
                                            }
205 14ad7326 pastith
                                        if (ja == null) {
206 14ad7326 pastith
                                                return arrayForm ? newja : newjo;
207 14ad7326 pastith
                                        }
208 14ad7326 pastith
                                }
209 14ad7326 pastith
                        }
210 14ad7326 pastith
                    }
211 14ad7326 pastith
                    } else {
212 14ad7326 pastith
                            if (ja != null) {
213 14ad7326 pastith
                                    ja.put(token instanceof String ? 
214 14ad7326 pastith
                                                    JSONObject.stringToValue((String)token) : token);
215 14ad7326 pastith
                            }
216 14ad7326 pastith
                    }
217 14ad7326 pastith
        }
218 14ad7326 pastith
    }
219 14ad7326 pastith
220 14ad7326 pastith
221 14ad7326 pastith
    /**
222 14ad7326 pastith
     * Convert a well-formed (but not necessarily valid) XML string into a
223 14ad7326 pastith
     * JSONArray using the JsonML transform. Each XML tag is represented as
224 14ad7326 pastith
     * a JSONArray in which the first element is the tag name. If the tag has
225 14ad7326 pastith
     * attributes, then the second element will be JSONObject containing the
226 14ad7326 pastith
     * name/value pairs. If the tag contains children, then strings and
227 14ad7326 pastith
     * JSONArrays will represent the child tags.
228 14ad7326 pastith
     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
229 14ad7326 pastith
     * @param string The source string.
230 14ad7326 pastith
     * @return A JSONArray containing the structured data from the XML string.
231 14ad7326 pastith
     * @throws JSONException
232 14ad7326 pastith
     */
233 14ad7326 pastith
    public static JSONArray toJSONArray(String string) throws JSONException {
234 14ad7326 pastith
            return toJSONArray(new XMLTokener(string));
235 14ad7326 pastith
    }
236 14ad7326 pastith
237 14ad7326 pastith
238 14ad7326 pastith
    /**
239 14ad7326 pastith
     * Convert a well-formed (but not necessarily valid) XML string into a
240 14ad7326 pastith
     * JSONArray using the JsonML transform. Each XML tag is represented as
241 14ad7326 pastith
     * a JSONArray in which the first element is the tag name. If the tag has
242 14ad7326 pastith
     * attributes, then the second element will be JSONObject containing the
243 14ad7326 pastith
     * name/value pairs. If the tag contains children, then strings and
244 14ad7326 pastith
     * JSONArrays will represent the child content and tags.
245 14ad7326 pastith
     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
246 14ad7326 pastith
     * @param x An XMLTokener.
247 14ad7326 pastith
     * @return A JSONArray containing the structured data from the XML string.
248 14ad7326 pastith
     * @throws JSONException
249 14ad7326 pastith
     */
250 14ad7326 pastith
    public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
251 14ad7326 pastith
            return (JSONArray)parse(x, true, null);
252 14ad7326 pastith
    }
253 14ad7326 pastith
254 14ad7326 pastith
255 14ad7326 pastith
    
256 14ad7326 pastith
    /**
257 14ad7326 pastith
     * Convert a well-formed (but not necessarily valid) XML string into a
258 14ad7326 pastith
     * JSONObject using the JsonML transform. Each XML tag is represented as
259 14ad7326 pastith
     * a JSONObject with a "tagName" property. If the tag has attributes, then 
260 14ad7326 pastith
     * the attributes will be in the JSONObject as properties. If the tag 
261 14ad7326 pastith
     * contains children, the object will have a "childNodes" property which 
262 14ad7326 pastith
     * will be an array of strings and JsonML JSONObjects.
263 14ad7326 pastith

264 14ad7326 pastith
     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
265 14ad7326 pastith
     * @param x An XMLTokener of the XML source text.
266 14ad7326 pastith
     * @return A JSONObject containing the structured data from the XML string.
267 14ad7326 pastith
     * @throws JSONException
268 14ad7326 pastith
     */
269 14ad7326 pastith
    public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
270 14ad7326 pastith
               return (JSONObject)parse(x, false, null);
271 14ad7326 pastith
    }
272 14ad7326 pastith
    /**
273 14ad7326 pastith
     * Convert a well-formed (but not necessarily valid) XML string into a
274 14ad7326 pastith
     * JSONObject using the JsonML transform. Each XML tag is represented as
275 14ad7326 pastith
     * a JSONObject with a "tagName" property. If the tag has attributes, then 
276 14ad7326 pastith
     * the attributes will be in the JSONObject as properties. If the tag 
277 14ad7326 pastith
     * contains children, the object will have a "childNodes" property which 
278 14ad7326 pastith
     * will be an array of strings and JsonML JSONObjects.
279 14ad7326 pastith

280 14ad7326 pastith
     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
281 14ad7326 pastith
     * @param string The XML source text.
282 14ad7326 pastith
     * @return A JSONObject containing the structured data from the XML string.
283 14ad7326 pastith
     * @throws JSONException
284 14ad7326 pastith
     */
285 14ad7326 pastith
    public static JSONObject toJSONObject(String string) throws JSONException {
286 14ad7326 pastith
            return toJSONObject(new XMLTokener(string));
287 14ad7326 pastith
    }
288 14ad7326 pastith
289 14ad7326 pastith
290 14ad7326 pastith
    /**
291 14ad7326 pastith
     * Reverse the JSONML transformation, making an XML text from a JSONArray.
292 14ad7326 pastith
     * @param ja A JSONArray.
293 14ad7326 pastith
     * @return An XML string.
294 14ad7326 pastith
     * @throws JSONException
295 14ad7326 pastith
     */
296 14ad7326 pastith
    public static String toString(JSONArray ja) throws JSONException {
297 14ad7326 pastith
            Object                 e;
298 14ad7326 pastith
            int                         i;
299 14ad7326 pastith
            JSONObject   jo;
300 14ad7326 pastith
            String       k;
301 14ad7326 pastith
            Iterator     keys;
302 14ad7326 pastith
            int                         length;
303 14ad7326 pastith
            StringBuffer sb = new StringBuffer();
304 14ad7326 pastith
            String       tagName;
305 14ad7326 pastith
            String       v;
306 14ad7326 pastith
            
307 14ad7326 pastith
// Emit <tagName            
308 14ad7326 pastith
            
309 14ad7326 pastith
            tagName = ja.getString(0);
310 14ad7326 pastith
                XML.noSpace(tagName);
311 14ad7326 pastith
                tagName = XML.escape(tagName);
312 14ad7326 pastith
                sb.append('<');
313 14ad7326 pastith
                sb.append(tagName);
314 14ad7326 pastith
                
315 14ad7326 pastith
                e = ja.opt(1);
316 14ad7326 pastith
                if (e instanceof JSONObject) {
317 14ad7326 pastith
                        i = 2;
318 14ad7326 pastith
                        jo = (JSONObject)e;
319 14ad7326 pastith
                        
320 14ad7326 pastith
// Emit the attributes
321 14ad7326 pastith
                        
322 14ad7326 pastith
                keys = jo.keys();
323 14ad7326 pastith
                while (keys.hasNext()) {
324 14ad7326 pastith
                    k = keys.next().toString();
325 14ad7326 pastith
                    XML.noSpace(k);
326 14ad7326 pastith
                    v = jo.optString(k);
327 14ad7326 pastith
                    if (v != null) {
328 14ad7326 pastith
                            sb.append(' ');
329 14ad7326 pastith
                            sb.append(XML.escape(k));
330 14ad7326 pastith
                            sb.append('=');
331 14ad7326 pastith
                            sb.append('"');
332 14ad7326 pastith
                            sb.append(XML.escape(v));
333 14ad7326 pastith
                            sb.append('"');
334 14ad7326 pastith
                    }
335 14ad7326 pastith
                }  
336 14ad7326 pastith
                } else {
337 14ad7326 pastith
                        i = 1;
338 14ad7326 pastith
                }
339 14ad7326 pastith
                     
340 14ad7326 pastith
//Emit content in body
341 14ad7326 pastith
                    
342 14ad7326 pastith
                length = ja.length();
343 14ad7326 pastith
                if (i >= length) {
344 14ad7326 pastith
                sb.append('/');
345 14ad7326 pastith
                sb.append('>');
346 14ad7326 pastith
                } else {
347 14ad7326 pastith
                sb.append('>');
348 14ad7326 pastith
                        do {
349 14ad7326 pastith
                            e = ja.get(i);
350 14ad7326 pastith
                            i += 1;
351 14ad7326 pastith
                            if (e != null) {
352 14ad7326 pastith
                                    if (e instanceof String) {
353 14ad7326 pastith
                                            sb.append(XML.escape(e.toString()));
354 14ad7326 pastith
                                        } else if (e instanceof JSONObject) {
355 14ad7326 pastith
                                                sb.append(toString((JSONObject)e));
356 14ad7326 pastith
                                        } else if (e instanceof JSONArray) {
357 14ad7326 pastith
                                                sb.append(toString((JSONArray)e));
358 14ad7326 pastith
                                        }
359 14ad7326 pastith
                            }
360 14ad7326 pastith
                        } while (i < length);
361 14ad7326 pastith
                        sb.append('<');
362 14ad7326 pastith
                sb.append('/');
363 14ad7326 pastith
                        sb.append(tagName);
364 14ad7326 pastith
                sb.append('>');
365 14ad7326 pastith
            }
366 14ad7326 pastith
        return sb.toString();
367 14ad7326 pastith
    }
368 14ad7326 pastith
    
369 14ad7326 pastith
    /**
370 14ad7326 pastith
     * Reverse the JSONML transformation, making an XML text from a JSONObject.
371 14ad7326 pastith
     * The JSONObject must contain a "tagName" property. If it has children, 
372 14ad7326 pastith
     * then it must have a "childNodes" property containing an array of objects. 
373 14ad7326 pastith
     * The other properties are attributes with string values.
374 14ad7326 pastith
     * @param jo A JSONObject.
375 14ad7326 pastith
     * @return An XML string.
376 14ad7326 pastith
     * @throws JSONException
377 14ad7326 pastith
     */
378 14ad7326 pastith
        public static String toString(JSONObject jo) throws JSONException {
379 14ad7326 pastith
            StringBuffer sb = new StringBuffer();
380 14ad7326 pastith
            Object                 e;
381 14ad7326 pastith
            int          i;
382 14ad7326 pastith
            JSONArray    ja;
383 14ad7326 pastith
            String       k;
384 14ad7326 pastith
            Iterator     keys;
385 14ad7326 pastith
            int          len;
386 14ad7326 pastith
            String       tagName;
387 14ad7326 pastith
            String       v;
388 14ad7326 pastith
        
389 14ad7326 pastith
//Emit <tagName
390 14ad7326 pastith
        
391 14ad7326 pastith
                tagName = jo.optString("tagName");
392 14ad7326 pastith
                if (tagName == null) {
393 14ad7326 pastith
                        return XML.escape(jo.toString());
394 14ad7326 pastith
                }
395 14ad7326 pastith
                XML.noSpace(tagName);
396 14ad7326 pastith
                tagName = XML.escape(tagName);
397 14ad7326 pastith
                sb.append('<');
398 14ad7326 pastith
                sb.append(tagName);
399 14ad7326 pastith
        
400 14ad7326 pastith
//Emit the attributes
401 14ad7326 pastith
        
402 14ad7326 pastith
        keys = jo.keys();
403 14ad7326 pastith
        while (keys.hasNext()) {
404 14ad7326 pastith
            k = keys.next().toString();
405 14ad7326 pastith
            if (!k.equals("tagName") && !k.equals("childNodes")) {
406 14ad7326 pastith
                    XML.noSpace(k);
407 14ad7326 pastith
                    v = jo.optString(k);
408 14ad7326 pastith
                    if (v != null) {
409 14ad7326 pastith
                            sb.append(' ');
410 14ad7326 pastith
                            sb.append(XML.escape(k));
411 14ad7326 pastith
                            sb.append('=');
412 14ad7326 pastith
                            sb.append('"');
413 14ad7326 pastith
                            sb.append(XML.escape(v));
414 14ad7326 pastith
                            sb.append('"');
415 14ad7326 pastith
                    }
416 14ad7326 pastith
            }
417 14ad7326 pastith
        }    
418 14ad7326 pastith
                             
419 14ad7326 pastith
//Emit content in body
420 14ad7326 pastith
        
421 14ad7326 pastith
                ja = jo.optJSONArray("childNodes");
422 14ad7326 pastith
                if (ja == null) {
423 14ad7326 pastith
                sb.append('/');
424 14ad7326 pastith
                sb.append('>');
425 14ad7326 pastith
                } else {
426 14ad7326 pastith
                sb.append('>');
427 14ad7326 pastith
                        len = ja.length();
428 14ad7326 pastith
                        for (i = 0; i < len; i += 1) {
429 14ad7326 pastith
                            e = ja.get(i);
430 14ad7326 pastith
                            if (e != null) {
431 14ad7326 pastith
                                    if (e instanceof String) {
432 14ad7326 pastith
                                            sb.append(XML.escape(e.toString()));
433 14ad7326 pastith
                                        } else if (e instanceof JSONObject) {
434 14ad7326 pastith
                                                sb.append(toString((JSONObject)e));
435 14ad7326 pastith
                                        } else if (e instanceof JSONArray) {
436 14ad7326 pastith
                                                sb.append(toString((JSONArray)e));
437 14ad7326 pastith
                                        }
438 14ad7326 pastith
                            }
439 14ad7326 pastith
                        }
440 14ad7326 pastith
                        sb.append('<');
441 14ad7326 pastith
                sb.append('/');
442 14ad7326 pastith
                        sb.append(tagName);
443 14ad7326 pastith
                sb.append('>');
444 14ad7326 pastith
            }
445 14ad7326 pastith
        return sb.toString();
446 14ad7326 pastith
    }
447 14ad7326 pastith
}