annotate lib/org.json_2.0/src/org/json/XML.java @ 0:db87c1b7eb6d

initial
author dwinter
date Wed, 03 Nov 2010 12:18:46 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
db87c1b7eb6d initial
dwinter
parents:
diff changeset
1 package org.json;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
2
db87c1b7eb6d initial
dwinter
parents:
diff changeset
3 /*
db87c1b7eb6d initial
dwinter
parents:
diff changeset
4 Copyright (c) 2002 JSON.org
db87c1b7eb6d initial
dwinter
parents:
diff changeset
5
db87c1b7eb6d initial
dwinter
parents:
diff changeset
6 Permission is hereby granted, free of charge, to any person obtaining a copy
db87c1b7eb6d initial
dwinter
parents:
diff changeset
7 of this software and associated documentation files (the "Software"), to deal
db87c1b7eb6d initial
dwinter
parents:
diff changeset
8 in the Software without restriction, including without limitation the rights
db87c1b7eb6d initial
dwinter
parents:
diff changeset
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
db87c1b7eb6d initial
dwinter
parents:
diff changeset
10 copies of the Software, and to permit persons to whom the Software is
db87c1b7eb6d initial
dwinter
parents:
diff changeset
11 furnished to do so, subject to the following conditions:
db87c1b7eb6d initial
dwinter
parents:
diff changeset
12
db87c1b7eb6d initial
dwinter
parents:
diff changeset
13 The above copyright notice and this permission notice shall be included in all
db87c1b7eb6d initial
dwinter
parents:
diff changeset
14 copies or substantial portions of the Software.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
15
db87c1b7eb6d initial
dwinter
parents:
diff changeset
16 The Software shall be used for Good, not Evil.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
17
db87c1b7eb6d initial
dwinter
parents:
diff changeset
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
db87c1b7eb6d initial
dwinter
parents:
diff changeset
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
db87c1b7eb6d initial
dwinter
parents:
diff changeset
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
db87c1b7eb6d initial
dwinter
parents:
diff changeset
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
db87c1b7eb6d initial
dwinter
parents:
diff changeset
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
db87c1b7eb6d initial
dwinter
parents:
diff changeset
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
db87c1b7eb6d initial
dwinter
parents:
diff changeset
24 SOFTWARE.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
25 */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
26
db87c1b7eb6d initial
dwinter
parents:
diff changeset
27 import java.util.Iterator;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
28
db87c1b7eb6d initial
dwinter
parents:
diff changeset
29
db87c1b7eb6d initial
dwinter
parents:
diff changeset
30 /**
db87c1b7eb6d initial
dwinter
parents:
diff changeset
31 * This provides static methods to convert an XML text into a JSONObject,
db87c1b7eb6d initial
dwinter
parents:
diff changeset
32 * and to covert a JSONObject into an XML text.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
33 * @author JSON.org
db87c1b7eb6d initial
dwinter
parents:
diff changeset
34 * @version 2008-10-14
db87c1b7eb6d initial
dwinter
parents:
diff changeset
35 */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
36 public class XML {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
37
db87c1b7eb6d initial
dwinter
parents:
diff changeset
38 /** The Character '&'. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
39 public static final Character AMP = new Character('&');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
40
db87c1b7eb6d initial
dwinter
parents:
diff changeset
41 /** The Character '''. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
42 public static final Character APOS = new Character('\'');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
43
db87c1b7eb6d initial
dwinter
parents:
diff changeset
44 /** The Character '!'. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
45 public static final Character BANG = new Character('!');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
46
db87c1b7eb6d initial
dwinter
parents:
diff changeset
47 /** The Character '='. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
48 public static final Character EQ = new Character('=');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
49
db87c1b7eb6d initial
dwinter
parents:
diff changeset
50 /** The Character '>'. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
51 public static final Character GT = new Character('>');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
52
db87c1b7eb6d initial
dwinter
parents:
diff changeset
53 /** The Character '<'. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
54 public static final Character LT = new Character('<');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
55
db87c1b7eb6d initial
dwinter
parents:
diff changeset
56 /** The Character '?'. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
57 public static final Character QUEST = new Character('?');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
58
db87c1b7eb6d initial
dwinter
parents:
diff changeset
59 /** The Character '"'. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
60 public static final Character QUOT = new Character('"');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
61
db87c1b7eb6d initial
dwinter
parents:
diff changeset
62 /** The Character '/'. */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
63 public static final Character SLASH = new Character('/');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
64
db87c1b7eb6d initial
dwinter
parents:
diff changeset
65 /**
db87c1b7eb6d initial
dwinter
parents:
diff changeset
66 * Replace special characters with XML escapes:
db87c1b7eb6d initial
dwinter
parents:
diff changeset
67 * <pre>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
68 * &amp; <small>(ampersand)</small> is replaced by &amp;amp;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
69 * &lt; <small>(less than)</small> is replaced by &amp;lt;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
70 * &gt; <small>(greater than)</small> is replaced by &amp;gt;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
71 * &quot; <small>(double quote)</small> is replaced by &amp;quot;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
72 * </pre>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
73 * @param string The string to be escaped.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
74 * @return The escaped string.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
75 */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
76 public static String escape(String string) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
77 StringBuffer sb = new StringBuffer();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
78 for (int i = 0, len = string.length(); i < len; i++) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
79 char c = string.charAt(i);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
80 switch (c) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
81 case '&':
db87c1b7eb6d initial
dwinter
parents:
diff changeset
82 sb.append("&amp;");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
83 break;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
84 case '<':
db87c1b7eb6d initial
dwinter
parents:
diff changeset
85 sb.append("&lt;");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
86 break;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
87 case '>':
db87c1b7eb6d initial
dwinter
parents:
diff changeset
88 sb.append("&gt;");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
89 break;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
90 case '"':
db87c1b7eb6d initial
dwinter
parents:
diff changeset
91 sb.append("&quot;");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
92 break;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
93 default:
db87c1b7eb6d initial
dwinter
parents:
diff changeset
94 sb.append(c);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
95 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
96 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
97 return sb.toString();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
98 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
99
db87c1b7eb6d initial
dwinter
parents:
diff changeset
100 /**
db87c1b7eb6d initial
dwinter
parents:
diff changeset
101 * Throw an exception if the string contains whitespace.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
102 * Whitespace is not allowed in tagNames and attributes.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
103 * @param string
db87c1b7eb6d initial
dwinter
parents:
diff changeset
104 * @throws JSONException
db87c1b7eb6d initial
dwinter
parents:
diff changeset
105 */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
106 public static void noSpace(String string) throws JSONException {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
107 int i, length = string.length();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
108 if (length == 0) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
109 throw new JSONException("Empty string.");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
110 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
111 for (i = 0; i < length; i += 1) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
112 if (Character.isWhitespace(string.charAt(i))) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
113 throw new JSONException("'" + string +
db87c1b7eb6d initial
dwinter
parents:
diff changeset
114 "' contains a space character.");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
115 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
116 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
117 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
118
db87c1b7eb6d initial
dwinter
parents:
diff changeset
119 /**
db87c1b7eb6d initial
dwinter
parents:
diff changeset
120 * Scan the content following the named tag, attaching it to the context.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
121 * @param x The XMLTokener containing the source string.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
122 * @param context The JSONObject that will include the new material.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
123 * @param name The tag name.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
124 * @return true if the close tag is processed.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
125 * @throws JSONException
db87c1b7eb6d initial
dwinter
parents:
diff changeset
126 */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
127 private static boolean parse(XMLTokener x, JSONObject context,
db87c1b7eb6d initial
dwinter
parents:
diff changeset
128 String name) throws JSONException {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
129 char c;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
130 int i;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
131 String n;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
132 JSONObject o = null;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
133 String s;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
134 Object t;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
135
db87c1b7eb6d initial
dwinter
parents:
diff changeset
136 // Test for and skip past these forms:
db87c1b7eb6d initial
dwinter
parents:
diff changeset
137 // <!-- ... -->
db87c1b7eb6d initial
dwinter
parents:
diff changeset
138 // <! ... >
db87c1b7eb6d initial
dwinter
parents:
diff changeset
139 // <![ ... ]]>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
140 // <? ... ?>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
141 // Report errors for these forms:
db87c1b7eb6d initial
dwinter
parents:
diff changeset
142 // <>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
143 // <=
db87c1b7eb6d initial
dwinter
parents:
diff changeset
144 // <<
db87c1b7eb6d initial
dwinter
parents:
diff changeset
145
db87c1b7eb6d initial
dwinter
parents:
diff changeset
146 t = x.nextToken();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
147
db87c1b7eb6d initial
dwinter
parents:
diff changeset
148 // <!
db87c1b7eb6d initial
dwinter
parents:
diff changeset
149
db87c1b7eb6d initial
dwinter
parents:
diff changeset
150 if (t == BANG) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
151 c = x.next();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
152 if (c == '-') {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
153 if (x.next() == '-') {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
154 x.skipPast("-->");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
155 return false;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
156 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
157 x.back();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
158 } else if (c == '[') {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
159 t = x.nextToken();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
160 if (t.equals("CDATA")) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
161 if (x.next() == '[') {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
162 s = x.nextCDATA();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
163 if (s.length() > 0) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
164 context.accumulate("content", s);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
165 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
166 return false;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
167 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
168 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
169 throw x.syntaxError("Expected 'CDATA['");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
170 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
171 i = 1;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
172 do {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
173 t = x.nextMeta();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
174 if (t == null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
175 throw x.syntaxError("Missing '>' after '<!'.");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
176 } else if (t == LT) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
177 i += 1;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
178 } else if (t == GT) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
179 i -= 1;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
180 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
181 } while (i > 0);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
182 return false;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
183 } else if (t == QUEST) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
184
db87c1b7eb6d initial
dwinter
parents:
diff changeset
185 // <?
db87c1b7eb6d initial
dwinter
parents:
diff changeset
186
db87c1b7eb6d initial
dwinter
parents:
diff changeset
187 x.skipPast("?>");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
188 return false;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
189 } else if (t == SLASH) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
190
db87c1b7eb6d initial
dwinter
parents:
diff changeset
191 // Close tag </
db87c1b7eb6d initial
dwinter
parents:
diff changeset
192
db87c1b7eb6d initial
dwinter
parents:
diff changeset
193 t = x.nextToken();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
194 if (name == null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
195 throw x.syntaxError("Mismatched close tag" + t);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
196 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
197 if (!t.equals(name)) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
198 throw x.syntaxError("Mismatched " + name + " and " + t);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
199 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
200 if (x.nextToken() != GT) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
201 throw x.syntaxError("Misshaped close tag");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
202 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
203 return true;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
204
db87c1b7eb6d initial
dwinter
parents:
diff changeset
205 } else if (t instanceof Character) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
206 throw x.syntaxError("Misshaped tag");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
207
db87c1b7eb6d initial
dwinter
parents:
diff changeset
208 // Open tag <
db87c1b7eb6d initial
dwinter
parents:
diff changeset
209
db87c1b7eb6d initial
dwinter
parents:
diff changeset
210 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
211 n = (String)t;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
212 t = null;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
213 o = new JSONObject();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
214 for (;;) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
215 if (t == null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
216 t = x.nextToken();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
217 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
218
db87c1b7eb6d initial
dwinter
parents:
diff changeset
219 // attribute = value
db87c1b7eb6d initial
dwinter
parents:
diff changeset
220
db87c1b7eb6d initial
dwinter
parents:
diff changeset
221 if (t instanceof String) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
222 s = (String)t;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
223 t = x.nextToken();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
224 if (t == EQ) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
225 t = x.nextToken();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
226 if (!(t instanceof String)) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
227 throw x.syntaxError("Missing value");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
228 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
229 o.accumulate(s, JSONObject.stringToValue((String)t));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
230 t = null;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
231 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
232 o.accumulate(s, "");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
233 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
234
db87c1b7eb6d initial
dwinter
parents:
diff changeset
235 // Empty tag <.../>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
236
db87c1b7eb6d initial
dwinter
parents:
diff changeset
237 } else if (t == SLASH) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
238 if (x.nextToken() != GT) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
239 throw x.syntaxError("Misshaped tag");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
240 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
241 context.accumulate(n, o);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
242 return false;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
243
db87c1b7eb6d initial
dwinter
parents:
diff changeset
244 // Content, between <...> and </...>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
245
db87c1b7eb6d initial
dwinter
parents:
diff changeset
246 } else if (t == GT) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
247 for (;;) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
248 t = x.nextContent();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
249 if (t == null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
250 if (n != null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
251 throw x.syntaxError("Unclosed tag " + n);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
252 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
253 return false;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
254 } else if (t instanceof String) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
255 s = (String)t;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
256 if (s.length() > 0) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
257 o.accumulate("content", JSONObject.stringToValue(s));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
258 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
259
db87c1b7eb6d initial
dwinter
parents:
diff changeset
260 // Nested element
db87c1b7eb6d initial
dwinter
parents:
diff changeset
261
db87c1b7eb6d initial
dwinter
parents:
diff changeset
262 } else if (t == LT) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
263 if (parse(x, o, n)) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
264 if (o.length() == 0) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
265 context.accumulate(n, "");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
266 } else if (o.length() == 1 &&
db87c1b7eb6d initial
dwinter
parents:
diff changeset
267 o.opt("content") != null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
268 context.accumulate(n, o.opt("content"));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
269 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
270 context.accumulate(n, o);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
271 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
272 return false;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
273 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
274 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
275 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
276 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
277 throw x.syntaxError("Misshaped tag");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
278 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
279 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
280 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
281 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
282
db87c1b7eb6d initial
dwinter
parents:
diff changeset
283
db87c1b7eb6d initial
dwinter
parents:
diff changeset
284 /**
db87c1b7eb6d initial
dwinter
parents:
diff changeset
285 * Convert a well-formed (but not necessarily valid) XML string into a
db87c1b7eb6d initial
dwinter
parents:
diff changeset
286 * JSONObject. Some information may be lost in this transformation
db87c1b7eb6d initial
dwinter
parents:
diff changeset
287 * because JSON is a data format and XML is a document format. XML uses
db87c1b7eb6d initial
dwinter
parents:
diff changeset
288 * elements, attributes, and content text, while JSON uses unordered
db87c1b7eb6d initial
dwinter
parents:
diff changeset
289 * collections of name/value pairs and arrays of values. JSON does not
db87c1b7eb6d initial
dwinter
parents:
diff changeset
290 * does not like to distinguish between elements and attributes.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
291 * Sequences of similar elements are represented as JSONArrays. Content
db87c1b7eb6d initial
dwinter
parents:
diff changeset
292 * text may be placed in a "content" member. Comments, prologs, DTDs, and
db87c1b7eb6d initial
dwinter
parents:
diff changeset
293 * <code>&lt;[ [ ]]></code> are ignored.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
294 * @param string The source string.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
295 * @return A JSONObject containing the structured data from the XML string.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
296 * @throws JSONException
db87c1b7eb6d initial
dwinter
parents:
diff changeset
297 */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
298 public static JSONObject toJSONObject(String string) throws JSONException {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
299 JSONObject o = new JSONObject();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
300 XMLTokener x = new XMLTokener(string);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
301 while (x.more() && x.skipPast("<")) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
302 parse(x, o, null);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
303 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
304 return o;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
305 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
306
db87c1b7eb6d initial
dwinter
parents:
diff changeset
307
db87c1b7eb6d initial
dwinter
parents:
diff changeset
308 /**
db87c1b7eb6d initial
dwinter
parents:
diff changeset
309 * Convert a JSONObject into a well-formed, element-normal XML string.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
310 * @param o A JSONObject.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
311 * @return A string.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
312 * @throws JSONException
db87c1b7eb6d initial
dwinter
parents:
diff changeset
313 */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
314 public static String toString(Object o) throws JSONException {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
315 return toString(o, null);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
316 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
317
db87c1b7eb6d initial
dwinter
parents:
diff changeset
318
db87c1b7eb6d initial
dwinter
parents:
diff changeset
319 /**
db87c1b7eb6d initial
dwinter
parents:
diff changeset
320 * Convert a JSONObject into a well-formed, element-normal XML string.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
321 * @param o A JSONObject.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
322 * @param tagName The optional name of the enclosing tag.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
323 * @return A string.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
324 * @throws JSONException
db87c1b7eb6d initial
dwinter
parents:
diff changeset
325 */
db87c1b7eb6d initial
dwinter
parents:
diff changeset
326 public static String toString(Object o, String tagName)
db87c1b7eb6d initial
dwinter
parents:
diff changeset
327 throws JSONException {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
328 StringBuffer b = new StringBuffer();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
329 int i;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
330 JSONArray ja;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
331 JSONObject jo;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
332 String k;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
333 Iterator keys;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
334 int len;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
335 String s;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
336 Object v;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
337 if (o instanceof JSONObject) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
338
db87c1b7eb6d initial
dwinter
parents:
diff changeset
339 // Emit <tagName>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
340
db87c1b7eb6d initial
dwinter
parents:
diff changeset
341 if (tagName != null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
342 b.append('<');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
343 b.append(tagName);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
344 b.append('>');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
345 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
346
db87c1b7eb6d initial
dwinter
parents:
diff changeset
347 // Loop thru the keys.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
348
db87c1b7eb6d initial
dwinter
parents:
diff changeset
349 jo = (JSONObject)o;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
350 keys = jo.keys();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
351 while (keys.hasNext()) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
352 k = keys.next().toString();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
353 v = jo.opt(k);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
354 if (v == null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
355 v = "";
db87c1b7eb6d initial
dwinter
parents:
diff changeset
356 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
357 if (v instanceof String) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
358 s = (String)v;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
359 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
360 s = null;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
361 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
362
db87c1b7eb6d initial
dwinter
parents:
diff changeset
363 // Emit content in body
db87c1b7eb6d initial
dwinter
parents:
diff changeset
364
db87c1b7eb6d initial
dwinter
parents:
diff changeset
365 if (k.equals("content")) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
366 if (v instanceof JSONArray) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
367 ja = (JSONArray)v;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
368 len = ja.length();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
369 for (i = 0; i < len; i += 1) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
370 if (i > 0) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
371 b.append('\n');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
372 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
373 b.append(escape(ja.get(i).toString()));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
374 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
375 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
376 b.append(escape(v.toString()));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
377 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
378
db87c1b7eb6d initial
dwinter
parents:
diff changeset
379 // Emit an array of similar keys
db87c1b7eb6d initial
dwinter
parents:
diff changeset
380
db87c1b7eb6d initial
dwinter
parents:
diff changeset
381 } else if (v instanceof JSONArray) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
382 ja = (JSONArray)v;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
383 len = ja.length();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
384 for (i = 0; i < len; i += 1) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
385 v = ja.get(i);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
386 if (v instanceof JSONArray) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
387 b.append('<');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
388 b.append(k);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
389 b.append('>');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
390 b.append(toString(v));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
391 b.append("</");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
392 b.append(k);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
393 b.append('>');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
394 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
395 b.append(toString(v, k));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
396 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
397 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
398 } else if (v.equals("")) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
399 b.append('<');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
400 b.append(k);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
401 b.append("/>");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
402
db87c1b7eb6d initial
dwinter
parents:
diff changeset
403 // Emit a new tag <k>
db87c1b7eb6d initial
dwinter
parents:
diff changeset
404
db87c1b7eb6d initial
dwinter
parents:
diff changeset
405 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
406 b.append(toString(v, k));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
407 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
408 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
409 if (tagName != null) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
410
db87c1b7eb6d initial
dwinter
parents:
diff changeset
411 // Emit the </tagname> close tag
db87c1b7eb6d initial
dwinter
parents:
diff changeset
412
db87c1b7eb6d initial
dwinter
parents:
diff changeset
413 b.append("</");
db87c1b7eb6d initial
dwinter
parents:
diff changeset
414 b.append(tagName);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
415 b.append('>');
db87c1b7eb6d initial
dwinter
parents:
diff changeset
416 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
417 return b.toString();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
418
db87c1b7eb6d initial
dwinter
parents:
diff changeset
419 // XML does not have good support for arrays. If an array appears in a place
db87c1b7eb6d initial
dwinter
parents:
diff changeset
420 // where XML is lacking, synthesize an <array> element.
db87c1b7eb6d initial
dwinter
parents:
diff changeset
421
db87c1b7eb6d initial
dwinter
parents:
diff changeset
422 } else if (o instanceof JSONArray) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
423 ja = (JSONArray)o;
db87c1b7eb6d initial
dwinter
parents:
diff changeset
424 len = ja.length();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
425 for (i = 0; i < len; ++i) {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
426 v = ja.opt(i);
db87c1b7eb6d initial
dwinter
parents:
diff changeset
427 b.append(toString(v, (tagName == null) ? "array" : tagName));
db87c1b7eb6d initial
dwinter
parents:
diff changeset
428 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
429 return b.toString();
db87c1b7eb6d initial
dwinter
parents:
diff changeset
430 } else {
db87c1b7eb6d initial
dwinter
parents:
diff changeset
431 s = (o == null) ? "null" : escape(o.toString());
db87c1b7eb6d initial
dwinter
parents:
diff changeset
432 return (tagName == null) ? "\"" + s + "\"" :
db87c1b7eb6d initial
dwinter
parents:
diff changeset
433 (s.length() == 0) ? "<" + tagName + "/>" :
db87c1b7eb6d initial
dwinter
parents:
diff changeset
434 "<" + tagName + ">" + s + "</" + tagName + ">";
db87c1b7eb6d initial
dwinter
parents:
diff changeset
435 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
436 }
db87c1b7eb6d initial
dwinter
parents:
diff changeset
437 }