root/tools/routingservice/branches/wrs-2.0/lib/org/json/JSONML.java

Revision 290, 14.5 KB (checked in by anton, 20 months ago)

First working version with JSON input and GML output for route service

Line 
1package org.json;
2
3/*
4Copyright (c) 2008 JSON.org
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16The Software shall be used for Good, not Evil.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24SOFTWARE.
25*/
26
27import java.util.Iterator;
28
29
30/**
31 * This provides static methods to convert an XML text into a JSONArray or
32 * JSONObject, and to covert a JSONArray or JSONObject into an XML text using
33 * the JsonML transform.
34 * @author JSON.org
35 * @version 2008-11-20
36 */
37public class JSONML {
38               
39    /**
40     * Parse XML values and store them in a JSONArray.
41     * @param x       The XMLTokener containing the source string.
42     * @param arrayForm true if array form, false if object form.
43     * @param ja      The JSONArray that is containing the current tag or null
44     *     if we are at the outermost level.
45     * @return A JSONArray if the value is the outermost tag, otherwise null.
46     * @throws JSONException
47     */
48    private static Object parse(XMLTokener x, boolean arrayForm,
49                JSONArray ja) throws JSONException {
50        String     attribute;
51        char       c;
52        String     closeTag = null;
53        int        i;
54        JSONArray  newja = null;
55        JSONObject newjo = null;
56        Object     token;
57        String     tagName = null;
58       
59// Test for and skip past these forms:
60//      <!-- ... -->
61//      <![  ... ]]>
62//      <!   ...   >
63//      <?   ...  ?>
64       
65        while (true) {
66                token = x.nextContent();
67                if (token == XML.LT) {
68                        token = x.nextToken();
69                        if (token instanceof Character) {
70                                if (token == XML.SLASH) {
71
72// Close tag </
73
74                                        token = x.nextToken();
75                                        if (!(token instanceof String)) {
76                                                throw new JSONException(
77                                                                "Expected a closing name instead of '" +
78                                                                token + "'.");
79                                        }
80                                    if (x.nextToken() != XML.GT) {
81                                        throw x.syntaxError("Misshaped close tag");
82                                    }
83                                    return token;
84                                } else if (token == XML.BANG) {
85                       
86// <!
87               
88                                    c = x.next();
89                                    if (c == '-') {
90                                        if (x.next() == '-') {
91                                            x.skipPast("-->");
92                                        }
93                                        x.back();
94                                    } else if (c == '[') {
95                                        token = x.nextToken();
96                                        if (token.equals("CDATA") && x.next() == '[') {
97                                                if (ja != null) {
98                                                        ja.put(x.nextCDATA());
99                                                }
100                                        } else {
101                                                throw x.syntaxError("Expected 'CDATA['");
102                                        }
103                                    } else {
104                                            i = 1;
105                                            do {
106                                                token = x.nextMeta();
107                                                if (token == null) {
108                                                    throw x.syntaxError("Missing '>' after '<!'.");
109                                                } else if (token == XML.LT) {
110                                                    i += 1;
111                                                } else if (token == XML.GT) {
112                                                    i -= 1;
113                                                }
114                                            } while (i > 0);
115                                    }
116                                } else if (token == XML.QUEST) {
117
118// <?
119
120                                        x.skipPast("?>");
121                                } else {
122                                    throw x.syntaxError("Misshaped tag");
123                                }
124
125// Open tag <
126
127                        } else {
128                                if (!(token instanceof String)) {
129                                    throw x.syntaxError("Bad tagName '" + token + "'.");                                       
130                                }
131                                tagName = (String)token;
132                            newja = new JSONArray();           
133                            newjo = new JSONObject();
134                                if (arrayForm) {
135                                    newja.put(tagName);
136                                    if (ja != null) {
137                                        ja.put(newja);
138                                    }
139                                } else {
140                                        newjo.put("tagName", tagName);
141                                        if (ja != null) {
142                                        ja.put(newjo);
143                                    }
144                                }
145                            token = null;
146                            for (;;) {
147                                if (token == null) {
148                                    token = x.nextToken();
149                                }
150                                if (token == null) {
151                                        throw x.syntaxError("Misshaped tag");
152                                }
153                                if (!(token instanceof String)) {
154                                        break;
155                                }
156
157//                            attribute = value
158
159                            attribute = (String)token;
160                                        if (!arrayForm && (attribute == "tagName" || attribute == "childNode")) {
161                            throw x.syntaxError("Reserved attribute.");                                         
162                                        }
163                            token = x.nextToken();
164                            if (token == XML.EQ) {
165                                token = x.nextToken();
166                                if (!(token instanceof String)) {
167                                    throw x.syntaxError("Missing value");
168                                }
169                                newjo.accumulate(attribute, JSONObject.stringToValue((String)token));
170                                token = null;
171                            } else {
172                                newjo.accumulate(attribute, "");
173                            }
174                            }
175                    if (arrayForm && newjo.length() > 0) {
176                        newja.put(newjo);
177                    }
178
179// Empty tag <.../>
180
181                        if (token == XML.SLASH) {
182                            if (x.nextToken() != XML.GT) {
183                                throw x.syntaxError("Misshaped tag");
184                            }
185                            if (ja == null) {
186                                if (arrayForm) {
187                                        return newja;
188                                } else {
189                                        return newjo;
190                                }
191                            }
192
193// Content, between <...> and </...>
194
195                        } else {
196                                if (token != XML.GT) {
197                                        throw x.syntaxError("Misshaped tag");
198                                }
199                                closeTag = (String)parse(x, arrayForm, newja);
200                                if (closeTag != null) {
201                                        if (!closeTag.equals(tagName)) {
202                                                throw x.syntaxError("Mismatched '" + tagName +
203                                                                "' and '" + closeTag + "'");
204                                                }
205                                        tagName = null;
206                                        if (!arrayForm && newja.length() > 0) {
207                                                newjo.put("childNodes", newja);
208                                        }
209                                        if (ja == null) {
210                                        if (arrayForm) {
211                                                return newja;
212                                        } else {
213                                                return newjo;
214                                        }
215                                        }
216                                }
217                        }
218                    }
219                    } else {
220                        if (ja != null) {
221                                ja.put(token instanceof String ?
222                                                JSONObject.stringToValue((String)token) : token);
223                        }
224                    }
225        }
226    }
227
228
229    /**
230     * Convert a well-formed (but not necessarily valid) XML string into a
231     * JSONArray using the JsonML transform. Each XML tag is represented as
232     * a JSONArray in which the first element is the tag name. If the tag has
233     * attributes, then the second element will be JSONObject containing the
234     * name/value pairs. If the tag contains children, then strings and
235     * JSONArrays will represent the child tags.
236     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
237     * @param string The source string.
238     * @return A JSONArray containing the structured data from the XML string.
239     * @throws JSONException
240     */
241    public static JSONArray toJSONArray(String string) throws JSONException {
242        return toJSONArray(new XMLTokener(string));
243    }
244
245
246    /**
247     * Convert a well-formed (but not necessarily valid) XML string into a
248     * JSONArray using the JsonML transform. Each XML tag is represented as
249     * a JSONArray in which the first element is the tag name. If the tag has
250     * attributes, then the second element will be JSONObject containing the
251     * name/value pairs. If the tag contains children, then strings and
252     * JSONArrays will represent the child content and tags.
253     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
254     * @param x An XMLTokener.
255     * @return A JSONArray containing the structured data from the XML string.
256     * @throws JSONException
257     */
258    public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
259        return (JSONArray)parse(x, true, null);
260    }
261
262
263   
264    /**
265     * Convert a well-formed (but not necessarily valid) XML string into a
266     * JSONObject using the JsonML transform. Each XML tag is represented as
267     * a JSONObject with a "tagName" property. If the tag has attributes, then
268     * the attributes will be in the JSONObject as properties. If the tag
269     * contains children, the object will have a "childNodes" property which
270     * will be an array of strings and JsonML JSONObjects.
271
272     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
273     * @param x An XMLTokener of the XML source text.
274     * @return A JSONObject containing the structured data from the XML string.
275     * @throws JSONException
276     */
277    public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
278        return (JSONObject)parse(x, false, null);
279    }
280    /**
281     * Convert a well-formed (but not necessarily valid) XML string into a
282     * JSONObject using the JsonML transform. Each XML tag is represented as
283     * a JSONObject with a "tagName" property. If the tag has attributes, then
284     * the attributes will be in the JSONObject as properties. If the tag
285     * contains children, the object will have a "childNodes" property which
286     * will be an array of strings and JsonML JSONObjects.
287
288     * Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code> are ignored.
289     * @param string The XML source text.
290     * @return A JSONObject containing the structured data from the XML string.
291     * @throws JSONException
292     */
293    public static JSONObject toJSONObject(String string) throws JSONException {
294        return toJSONObject(new XMLTokener(string));
295    }
296
297
298    /**
299     * Reverse the JSONML transformation, making an XML text from a JSONArray.
300     * @param ja A JSONArray.
301     * @return An XML string.
302     * @throws JSONException
303     */
304    public static String toString(JSONArray ja) throws JSONException {
305        Object           e;
306        int                      i;
307        JSONObject   jo;
308        String       k;
309            Iterator     keys;
310            int                  length;
311        StringBuffer sb = new StringBuffer();
312            String       tagName;
313            String       v;
314           
315// Emit <tagName           
316       
317        tagName = ja.getString(0);
318                XML.noSpace(tagName);
319                tagName = XML.escape(tagName);
320                sb.append('<');
321                sb.append(tagName);
322               
323                e = ja.opt(1);
324                if (e instanceof JSONObject) {
325                        i = 2;
326                        jo = (JSONObject)e;
327                       
328// Emit the attributes
329                       
330                keys = jo.keys();
331                while (keys.hasNext()) {
332                    k = keys.next().toString();
333                XML.noSpace(k);
334                    v = jo.optString(k);
335                    if (v != null) {
336                            sb.append(' ');
337                            sb.append(XML.escape(k));
338                            sb.append('=');
339                            sb.append('"');
340                            sb.append(XML.escape(v));
341                            sb.append('"');
342                    }
343                } 
344                } else {
345                        i = 1;
346                }
347               
348//Emit content in body
349               
350                length = ja.length();
351                if (i >= length) {
352                sb.append('/');
353                sb.append('>');
354                } else {
355                sb.append('>');
356                        do {
357                            e = ja.get(i);
358                            i += 1;
359                            if (e != null) {
360                                if (e instanceof String) {
361                                        sb.append(XML.escape(e.toString()));
362                                        } else if (e instanceof JSONObject) {
363                                                sb.append(toString((JSONObject)e));
364                                        } else if (e instanceof JSONArray) {
365                                                sb.append(toString((JSONArray)e));
366                                        }
367                            }
368                        } while (i < length);
369                        sb.append('<');
370                sb.append('/');
371                        sb.append(tagName);
372                sb.append('>');
373            }
374        return sb.toString();
375    }
376   
377    /**
378     * Reverse the JSONML transformation, making an XML text from a JSONObject.
379     * The JSONObject must contain a "tagName" property. If it has children,
380     * then it must have a "childNodes" property containing an array of objects.
381     * The other properties are attributes with string values.
382     * @param jo A JSONObject.
383     * @return An XML string.
384     * @throws JSONException
385     */
386        public static String toString(JSONObject jo) throws JSONException {
387            StringBuffer sb = new StringBuffer();
388            Object               e;
389            int          i;
390            JSONArray    ja;
391            String       k;
392            Iterator     keys;
393            int          len;
394            String       tagName;
395            String       v;
396       
397//Emit <tagName
398       
399                tagName = jo.optString("tagName");
400                if (tagName == null) {
401                        return XML.escape(jo.toString());
402                }
403                XML.noSpace(tagName);
404                tagName = XML.escape(tagName);
405                sb.append('<');
406                sb.append(tagName);
407       
408//Emit the attributes
409       
410        keys = jo.keys();
411        while (keys.hasNext()) {
412            k = keys.next().toString();
413            if (!k.equals("tagName") && !k.equals("childNodes")) {
414                XML.noSpace(k);
415                    v = jo.optString(k);
416                    if (v != null) {
417                            sb.append(' ');
418                            sb.append(XML.escape(k));
419                            sb.append('=');
420                            sb.append('"');
421                            sb.append(XML.escape(v));
422                            sb.append('"');
423                    }
424            }
425        }   
426                       
427//Emit content in body
428       
429                ja = jo.optJSONArray("childNodes");
430                if (ja == null) {
431                sb.append('/');
432                sb.append('>');
433                } else {
434                sb.append('>');
435                        len = ja.length();
436                        for (i = 0; i < len; i += 1) {
437                            e = ja.get(i);
438                            if (e != null) {
439                                if (e instanceof String) {
440                                        sb.append(XML.escape(e.toString()));
441                                        } else if (e instanceof JSONObject) {
442                                                sb.append(toString((JSONObject)e));
443                                        } else if (e instanceof JSONArray) {
444                                                sb.append(toString((JSONArray)e));
445                                        }
446                            }
447                        }
448                        sb.append('<');
449                sb.append('/');
450                        sb.append(tagName);
451                sb.append('>');
452            }
453        return sb.toString();
454    }
455}
Note: See TracBrowser for help on using the browser.