28 Commits

Author SHA1 Message Date
Sean Leary
07a0f60b6e Merge pull request #195 from publishing-systems/master
Java 1.6 compatibility.
2016-02-12 18:10:13 -06:00
skreutzer
60349ece54 Java 1.6 compatibility. 2016-02-08 23:30:27 -05:00
Sean Leary
ba2585fe6c Version date 2016-01-30 15:45:11 -06:00
Sean Leary
93c79ca566 Version date 2016-01-30 15:44:41 -06:00
Sean Leary
62486fdea4 Version date 2016-01-30 15:44:08 -06:00
Sean Leary
97f1b2744f Merge pull request #188 from johnjaylward/FixNegativeZero
Fix negative zero
2016-01-30 15:42:34 -06:00
John J. Aylward
c2b3f2bdb1 adds back in the XML.stringToValue method, but deprecates it. 2016-01-27 15:21:11 -05:00
John J. Aylward
3007fc8ebe Removes custom XML stringToValue method in favor of keeping a consistent
implementation in JSONObject
2016-01-27 15:03:19 -05:00
John J. Aylward
39b1c0cb66 fixes error in -0 check 2016-01-27 10:45:23 -05:00
John J. Aylward
07b2d65e30 Fixes #187 -0 now returns as a double. 2016-01-27 10:39:31 -05:00
John J. Aylward
5b67330b71 Merge branch 'master' of https://github.com/douglascrockford/JSON-java 2016-01-27 09:53:03 -05:00
Sean Leary
9950350f12 Merge pull request #186 from douglascrockford/update-readme-with-number-info
Update README with number information
2016-01-03 14:52:50 -06:00
Sean Leary
2b2fac3eb1 Broke up some overly long lines. 2016-01-01 16:17:30 -06:00
Sean Leary
e2a0bb16a2 Update README with number information
See https://github.com/douglascrockford/JSON-java/issues/162
2016-01-01 14:11:02 -06:00
Sean Leary
a971736f5b Update version string for https://github.com/douglascrockford/JSON-java/pull/170 2016-01-01 13:52:12 -06:00
Sean Leary
757fd566ab Merge pull request #170 from johnjaylward/HandleArraysConsistently
Handle arrays consistently
2016-01-01 13:44:57 -06:00
Sean Leary
e6f5047742 Merge pull request #185 from douglascrockford/write-with-indent-params
change to public: write(writer, indentfactor, indent)
2015-12-30 15:06:07 -06:00
stleary
8688494876 change to public, write(writer, indentfactor, indent) 2015-12-23 19:53:30 -06:00
John J. Aylward
48302592cf Merge branch 'master' of https://github.com/douglascrockford/JSON-java 2015-12-09 10:07:36 -05:00
Sean Leary
03dd662e72 Merge pull request #180 from netheril96/my
Remove executable bit
2015-12-09 01:08:47 -06:00
Siyuan Ren
23cf659730 Remove executable permission bit from file mode 2015-12-09 09:50:59 +08:00
John J. Aylward
ec8f649467 Merge branch 'master' of https://github.com/douglascrockford/JSON-java 2015-12-08 09:27:54 -05:00
Sean Leary
39e3ccc671 Update version
Update version after merge of https://github.com/douglascrockford/JSON-java/pull/179
2015-12-05 20:14:15 -06:00
Sean Leary
2ec538f420 Merge pull request #179 from andrew-fletcher/UpdateJavaDocForJSONOBject
Remove throws JSONException JavaDoc from 2 methods that do not throw this exception.
2015-12-05 20:11:40 -06:00
Andrew Fletcher
cadba9400c Update JavaDoc for JSONObject Constructors
Two JSONObject constructors incorrectly specify a @throws JSONException
tag in the JavaDoc for those constructors. Remove the relevant JavaDoc.
2015-12-02 10:49:54 -08:00
John J. Aylward
105426b53f Formatting 2015-10-26 18:35:40 -04:00
John J. Aylward
7886c96204 Changes JSONArray for loops to use the new iterators. 2015-10-26 18:30:41 -04:00
John J. Aylward
91c6f09be8 Modifies XML output to be handled the same for a native java array as well as a JSONArray. 2015-10-26 18:17:37 -04:00
15 changed files with 187 additions and 192 deletions

2
CDL.java Executable file → Normal file
View File

@@ -41,7 +41,7 @@ SOFTWARE.
* The names for the elements in the JSONObjects can be taken from the names * The names for the elements in the JSONObjects can be taken from the names
* in the first row. * in the first row.
* @author JSON.org * @author JSON.org
* @version 2015-05-01 * @version 2015-12-09
*/ */
public class CDL { public class CDL {

2
Cookie.java Executable file → Normal file
View File

@@ -28,7 +28,7 @@ SOFTWARE.
* Convert a web browser cookie specification to a JSONObject and back. * Convert a web browser cookie specification to a JSONObject and back.
* JSON and Cookies are both notations for name/value pairs. * JSON and Cookies are both notations for name/value pairs.
* @author JSON.org * @author JSON.org
* @version 2014-05-03 * @version 2015-12-09
*/ */
public class Cookie { public class Cookie {

2
CookieList.java Executable file → Normal file
View File

@@ -29,7 +29,7 @@ import java.util.Iterator;
/** /**
* Convert a web browser cookie list string to a JSONObject and back. * Convert a web browser cookie list string to a JSONObject and back.
* @author JSON.org * @author JSON.org
* @version 2014-05-03 * @version 2015-12-09
*/ */
public class CookieList { public class CookieList {

2
HTTP.java Executable file → Normal file
View File

@@ -29,7 +29,7 @@ import java.util.Iterator;
/** /**
* Convert an HTTP header to a JSONObject and back. * Convert an HTTP header to a JSONObject and back.
* @author JSON.org * @author JSON.org
* @version 2014-05-03 * @version 2015-12-09
*/ */
public class HTTP { public class HTTP {

2
HTTPTokener.java Executable file → Normal file
View File

@@ -28,7 +28,7 @@ SOFTWARE.
* The HTTPTokener extends the JSONTokener to provide additional methods * The HTTPTokener extends the JSONTokener to provide additional methods
* for the parsing of HTTP headers. * for the parsing of HTTP headers.
* @author JSON.org * @author JSON.org
* @version 2014-05-03 * @version 2015-12-09
*/ */
public class HTTPTokener extends JSONTokener { public class HTTPTokener extends JSONTokener {

View File

@@ -76,7 +76,7 @@ import java.util.Map;
* </ul> * </ul>
* *
* @author JSON.org * @author JSON.org
* @version 2015-10-29 * @version 2016-02-08
*/ */
public class JSONArray implements Iterable<Object> { public class JSONArray implements Iterable<Object> {
@@ -593,7 +593,9 @@ public class JSONArray implements Iterable<Object> {
return myE; return myE;
} }
return Enum.valueOf(clazz, val.toString()); return Enum.valueOf(clazz, val.toString());
} catch (IllegalArgumentException | NullPointerException e) { } catch (IllegalArgumentException e) {
return defaultValue;
} catch (NullPointerException e) {
return defaultValue; return defaultValue;
} }
} }
@@ -1083,6 +1085,8 @@ public class JSONArray implements Iterable<Object> {
* <p> * <p>
* Warning: This method assumes that the data structure is acyclical. * Warning: This method assumes that the data structure is acyclical.
* *
* @param writer
* Writes the serialized JSON
* @param indentFactor * @param indentFactor
* The number of spaces to add to each level of indentation. * The number of spaces to add to each level of indentation.
* @param indent * @param indent
@@ -1090,7 +1094,7 @@ public class JSONArray implements Iterable<Object> {
* @return The writer. * @return The writer.
* @throws JSONException * @throws JSONException
*/ */
Writer write(Writer writer, int indentFactor, int indent) public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException { throws JSONException {
try { try {
boolean commanate = false; boolean commanate = false;

2
JSONException.java Executable file → Normal file
View File

@@ -4,7 +4,7 @@ package org.json;
* The JSONException is thrown by the JSON.org classes when things are amiss. * The JSONException is thrown by the JSON.org classes when things are amiss.
* *
* @author JSON.org * @author JSON.org
* @version 2015-10-18 * @version 2015-12-09
*/ */
public class JSONException extends RuntimeException { public class JSONException extends RuntimeException {
/** Serialization ID */ /** Serialization ID */

6
JSONML.java Executable file → Normal file
View File

@@ -33,7 +33,7 @@ import java.util.Iterator;
* the JsonML transform. * the JsonML transform.
* *
* @author JSON.org * @author JSON.org
* @version 2014-05-03 * @version 2016-01-30
*/ */
public class JSONML { public class JSONML {
@@ -174,7 +174,7 @@ public class JSONML {
if (!(token instanceof String)) { if (!(token instanceof String)) {
throw x.syntaxError("Missing value"); throw x.syntaxError("Missing value");
} }
newjo.accumulate(attribute, XML.stringToValue((String)token)); newjo.accumulate(attribute, JSONObject.stringToValue((String)token));
token = null; token = null;
} else { } else {
newjo.accumulate(attribute, ""); newjo.accumulate(attribute, "");
@@ -227,7 +227,7 @@ public class JSONML {
} else { } else {
if (ja != null) { if (ja != null) {
ja.put(token instanceof String ja.put(token instanceof String
? XML.stringToValue((String)token) ? JSONObject.stringToValue((String)token)
: token); : token);
} }
} }

39
JSONObject.java Executable file → Normal file
View File

@@ -30,7 +30,8 @@ import java.io.Writer;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.math.*; import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection; import java.util.Collection;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
@@ -92,7 +93,7 @@ import java.util.Set;
* </ul> * </ul>
* *
* @author JSON.org * @author JSON.org
* @version 2015-10-29 * @version 2016-02-08
*/ */
public class JSONObject { public class JSONObject {
/** /**
@@ -165,10 +166,6 @@ public class JSONObject {
* A JSONObject. * A JSONObject.
* @param names * @param names
* An array of strings. * An array of strings.
* @throws JSONException
* @exception JSONException
* If a value is a non-finite number or if a name is
* duplicated.
*/ */
public JSONObject(JSONObject jo, String[] names) { public JSONObject(JSONObject jo, String[] names) {
this(); this();
@@ -241,7 +238,6 @@ public class JSONObject {
* @param map * @param map
* A map object that can be used to initialize the contents of * A map object that can be used to initialize the contents of
* the JSONObject. * the JSONObject.
* @throws JSONException
*/ */
public JSONObject(Map<?, ?> map) { public JSONObject(Map<?, ?> map) {
this.map = new HashMap<String, Object>(); this.map = new HashMap<String, Object>();
@@ -905,7 +901,9 @@ public class JSONObject {
return myE; return myE;
} }
return Enum.valueOf(clazz, val.toString()); return Enum.valueOf(clazz, val.toString());
} catch (IllegalArgumentException | NullPointerException e) { } catch (IllegalArgumentException e) {
return defaultValue;
} catch (NullPointerException e) {
return defaultValue; return defaultValue;
} }
} }
@@ -1482,7 +1480,6 @@ public class JSONObject {
* @return A simple JSON value. * @return A simple JSON value.
*/ */
public static Object stringToValue(String string) { public static Object stringToValue(String string) {
Double d;
if (string.equals("")) { if (string.equals("")) {
return string; return string;
} }
@@ -1501,23 +1498,23 @@ public class JSONObject {
* produced, then the value will just be a string. * produced, then the value will just be a string.
*/ */
char b = string.charAt(0); char initial = string.charAt(0);
if ((b >= '0' && b <= '9') || b == '-') { if ((initial >= '0' && initial <= '9') || initial == '-') {
try { try {
if (string.indexOf('.') > -1 || string.indexOf('e') > -1 if (string.indexOf('.') > -1 || string.indexOf('e') > -1
|| string.indexOf('E') > -1) { || string.indexOf('E') > -1
d = Double.valueOf(string); || "-0".equals(string)) {
Double d = Double.valueOf(string);
if (!d.isInfinite() && !d.isNaN()) { if (!d.isInfinite() && !d.isNaN()) {
return d; return d;
} }
} else { } else {
Long myLong = new Long(string); Long myLong = new Long(string);
if (string.equals(myLong.toString())) { if (string.equals(myLong.toString())) {
if (myLong == myLong.intValue()) { if (myLong.longValue() == myLong.intValue()) {
return myLong.intValue(); return Integer.valueOf(myLong.intValue());
} else {
return myLong;
} }
return myLong;
} }
} }
} catch (Exception ignore) { } catch (Exception ignore) {
@@ -1786,10 +1783,16 @@ public class JSONObject {
* <p> * <p>
* Warning: This method assumes that the data structure is acyclical. * Warning: This method assumes that the data structure is acyclical.
* *
* @param writer
* Writes the serialized JSON
* @param indentFactor
* The number of spaces to add to each level of indentation.
* @param indent
* The indention of the top level.
* @return The writer. * @return The writer.
* @throws JSONException * @throws JSONException
*/ */
Writer write(Writer writer, int indentFactor, int indent) public Writer write(Writer writer, int indentFactor, int indent)
throws JSONException { throws JSONException {
try { try {
boolean commanate = false; boolean commanate = false;

0
JSONString.java Executable file → Normal file
View File

2
JSONStringer.java Executable file → Normal file
View File

@@ -54,7 +54,7 @@ import java.io.StringWriter;
* <p> * <p>
* This can sometimes be easier than using a JSONObject to build a string. * This can sometimes be easier than using a JSONObject to build a string.
* @author JSON.org * @author JSON.org
* @version 2008-09-18 * @version 2015-12-09
*/ */
public class JSONStringer extends JSONWriter { public class JSONStringer extends JSONWriter {
/** /**

2
JSONWriter.java Executable file → Normal file
View File

@@ -54,7 +54,7 @@ SOFTWARE.
* <p> * <p>
* This can sometimes be easier than using a JSONObject to build a string. * This can sometimes be easier than using a JSONObject to build a string.
* @author JSON.org * @author JSON.org
* @version 2011-11-24 * @version 2015-12-09
*/ */
public class JSONWriter { public class JSONWriter {
private static final int maxdepth = 200; private static final int maxdepth = 200;

18
README Executable file → Normal file
View File

@@ -61,14 +61,26 @@ JSONML.java: JSONML provides support for converting between JSONML and XML.
XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text. XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text.
Unit tests are maintained in a separate project. Contributing developers can test JSON-java pull requests with the code in this project: https://github.com/stleary/JSON-Java-unit-test Unit tests are maintained in a separate project. Contributing developers can test
JSON-java pull requests with the code in this project:
https://github.com/stleary/JSON-Java-unit-test
Numeric types in this package comply with ECMA-404: The JSON Data Interchange Format
(http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf) and
RFC 7159: The JavaScript Object Notation (JSON) Data Interchange Format
(https://tools.ietf.org/html/rfc7159#section-6).
This package fully supports Integer, Long, and Double Java types. Partial support
for BigInteger and BigDecimal values in JSONObject and JSONArray objects is provided
in the form of get(), opt(), and put() API methods.
Release history: Release history:
20151123 JSONObject and JSONArray initialization with generics. Contains the 20151123 JSONObject and JSONArray initialization with generics. Contains the
latest code as of 23 Nov, 2015. latest code as of 23 Nov, 2015.
20150729 Checkpoint for Maven central repository release. Contains the latest code as of 29 July, 2015. 20150729 Checkpoint for Maven central repository release. Contains the latest code
as of 29 July, 2015.
JSON-java releases can be found by searching the Maven repository for groupId "org.json" and artifactId "json". For example: JSON-java releases can be found by searching the Maven repository for groupId "org.json"
and artifactId "json". For example:
https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.json%22%20AND%20a%3A%22json%22 https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.json%22%20AND%20a%3A%22json%22

182
XML.java Executable file → Normal file
View File

@@ -27,11 +27,13 @@ SOFTWARE.
import java.util.Iterator; import java.util.Iterator;
/** /**
* This provides static methods to convert an XML text into a JSONObject, * This provides static methods to convert an XML text into a JSONObject, and to
* and to covert a JSONObject into an XML text. * covert a JSONObject into an XML text.
*
* @author JSON.org * @author JSON.org
* @version 2015-10-18 * @version 2016-01-30
*/ */
@SuppressWarnings("boxing")
public class XML { public class XML {
/** The Character '&amp;'. */ /** The Character '&amp;'. */
@@ -63,13 +65,16 @@ public class XML {
/** /**
* Replace special characters with XML escapes: * Replace special characters with XML escapes:
*
* <pre> * <pre>
* &amp; <small>(ampersand)</small> is replaced by &amp;amp; * &amp; <small>(ampersand)</small> is replaced by &amp;amp;
* &lt; <small>(less than)</small> is replaced by &amp;lt; * &lt; <small>(less than)</small> is replaced by &amp;lt;
* &gt; <small>(greater than)</small> is replaced by &amp;gt; * &gt; <small>(greater than)</small> is replaced by &amp;gt;
* &quot; <small>(double quote)</small> is replaced by &amp;quot; * &quot; <small>(double quote)</small> is replaced by &amp;quot;
* </pre> * </pre>
* @param string The string to be escaped. *
* @param string
* The string to be escaped.
* @return The escaped string. * @return The escaped string.
*/ */
public static String escape(String string) { public static String escape(String string) {
@@ -100,9 +105,11 @@ public class XML {
} }
/** /**
* Throw an exception if the string contains whitespace. * Throw an exception if the string contains whitespace. Whitespace is not
* Whitespace is not allowed in tagNames and attributes. * allowed in tagNames and attributes.
* @param string A string. *
* @param string
* A string.
* @throws JSONException * @throws JSONException
*/ */
public static void noSpace(String string) throws JSONException { public static void noSpace(String string) throws JSONException {
@@ -112,22 +119,26 @@ public class XML {
} }
for (i = 0; i < length; i += 1) { for (i = 0; i < length; i += 1) {
if (Character.isWhitespace(string.charAt(i))) { if (Character.isWhitespace(string.charAt(i))) {
throw new JSONException("'" + string + throw new JSONException("'" + string
"' contains a space character."); + "' contains a space character.");
} }
} }
} }
/** /**
* Scan the content following the named tag, attaching it to the context. * Scan the content following the named tag, attaching it to the context.
* @param x The XMLTokener containing the source string. *
* @param context The JSONObject that will include the new material. * @param x
* @param name The tag name. * The XMLTokener containing the source string.
* @param context
* The JSONObject that will include the new material.
* @param name
* The tag name.
* @return true if the close tag is processed. * @return true if the close tag is processed.
* @throws JSONException * @throws JSONException
*/ */
private static boolean parse(XMLTokener x, JSONObject context, private static boolean parse(XMLTokener x, JSONObject context, String name)
String name) throws JSONException { throws JSONException {
char c; char c;
int i; int i;
JSONObject jsonobject = null; JSONObject jsonobject = null;
@@ -185,7 +196,6 @@ public class XML {
} else if (token == QUEST) { } else if (token == QUEST) {
// <? // <?
x.skipPast("?>"); x.skipPast("?>");
return false; return false;
} else if (token == SLASH) { } else if (token == SLASH) {
@@ -219,7 +229,6 @@ public class XML {
} }
// attribute = value // attribute = value
if (token instanceof String) { if (token instanceof String) {
string = (String) token; string = (String) token;
token = x.nextToken(); token = x.nextToken();
@@ -229,15 +238,15 @@ public class XML {
throw x.syntaxError("Missing value"); throw x.syntaxError("Missing value");
} }
jsonobject.accumulate(string, jsonobject.accumulate(string,
XML.stringToValue((String)token)); JSONObject.stringToValue((String) token));
token = null; token = null;
} else { } else {
jsonobject.accumulate(string, ""); jsonobject.accumulate(string, "");
} }
// Empty tag <.../>
} else if (token == SLASH) { } else if (token == SLASH) {
// Empty tag <.../>
if (x.nextToken() != GT) { if (x.nextToken() != GT) {
throw x.syntaxError("Misshaped tag"); throw x.syntaxError("Misshaped tag");
} }
@@ -248,9 +257,8 @@ public class XML {
} }
return false; return false;
// Content, between <...> and </...>
} else if (token == GT) { } else if (token == GT) {
// Content, between <...> and </...>
for (;;) { for (;;) {
token = x.nextContent(); token = x.nextContent();
if (token == null) { if (token == null) {
@@ -262,17 +270,16 @@ public class XML {
string = (String) token; string = (String) token;
if (string.length() > 0) { if (string.length() > 0) {
jsonobject.accumulate("content", jsonobject.accumulate("content",
XML.stringToValue(string)); JSONObject.stringToValue(string));
} }
// Nested element
} else if (token == LT) { } else if (token == LT) {
// Nested element
if (parse(x, jsonobject, tagName)) { if (parse(x, jsonobject, tagName)) {
if (jsonobject.length() == 0) { if (jsonobject.length() == 0) {
context.accumulate(tagName, ""); context.accumulate(tagName, "");
} else if (jsonobject.length() == 1 && } else if (jsonobject.length() == 1
jsonobject.opt("content") != null) { && jsonobject.opt("content") != null) {
context.accumulate(tagName, context.accumulate(tagName,
jsonobject.opt("content")); jsonobject.opt("content"));
} else { } else {
@@ -289,62 +296,31 @@ public class XML {
} }
} }
/** /**
* Try to convert a string into a number, boolean, or null. If the string * This method has been deprecated in favor of the
* can't be converted, return the string. This is much less ambitious than * {@link JSONObject.stringToValue(String)} method. Use it instead.
* JSONObject.stringToValue, especially because it does not attempt to *
* convert plus forms, octal forms, hex forms, or E forms lacking decimal * @deprecated Use {@link JSONObject#stringToValue(String)} instead.
* points. * @param string
* @param string A String. * @return JSON value of this string or the string
* @return A simple JSON value.
*/ */
public static Object stringToValue(String string) { public static Object stringToValue(String string) {
if ("true".equalsIgnoreCase(string)) { return JSONObject.stringToValue(string);
return Boolean.TRUE;
} }
if ("false".equalsIgnoreCase(string)) {
return Boolean.FALSE;
}
if ("null".equalsIgnoreCase(string)) {
return JSONObject.NULL;
}
// If it might be a number, try converting it, first as a Long, and then as a
// Double. If that doesn't work, return the string.
try {
char initial = string.charAt(0);
if (initial == '-' || (initial >= '0' && initial <= '9')) {
Long value = new Long(string);
if (value.toString().equals(string)) {
return value;
}
}
} catch (Exception ignore) {
try {
Double value = new Double(string);
if (value.toString().equals(string)) {
return value;
}
} catch (Exception ignoreAlso) {
}
}
return string;
}
/** /**
* Convert a well-formed (but not necessarily valid) XML string into a * Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject. Some information may be lost in this transformation * JSONObject. Some information may be lost in this transformation because
* because JSON is a data format and XML is a document format. XML uses * JSON is a data format and XML is a document format. XML uses elements,
* elements, attributes, and content text, while JSON uses unordered * attributes, and content text, while JSON uses unordered collections of
* collections of name/value pairs and arrays of values. JSON does not * name/value pairs and arrays of values. JSON does not does not like to
* does not like to distinguish between elements and attributes. * distinguish between elements and attributes. Sequences of similar
* Sequences of similar elements are represented as JSONArrays. Content * elements are represented as JSONArrays. Content text may be placed in a
* text may be placed in a "content" member. Comments, prologs, DTDs, and * "content" member. Comments, prologs, DTDs, and <code>&lt;[ [ ]]></code>
* <code>&lt;[ [ ]]></code> are ignored. * are ignored.
* @param string The source string. *
* @param string
* The source string.
* @return A JSONObject containing the structured data from the XML string. * @return A JSONObject containing the structured data from the XML string.
* @throws JSONException * @throws JSONException
*/ */
@@ -357,10 +333,11 @@ public class XML {
return jo; return jo;
} }
/** /**
* Convert a JSONObject into a well-formed, element-normal XML string. * Convert a JSONObject into a well-formed, element-normal XML string.
* @param object A JSONObject. *
* @param object
* A JSONObject.
* @return A string. * @return A string.
* @throws JSONException * @throws JSONException
*/ */
@@ -368,29 +345,29 @@ public class XML {
return toString(object, null); return toString(object, null);
} }
/** /**
* Convert a JSONObject into a well-formed, element-normal XML string. * Convert a JSONObject into a well-formed, element-normal XML string.
* @param object A JSONObject. *
* @param tagName The optional name of the enclosing tag. * @param object
* A JSONObject.
* @param tagName
* The optional name of the enclosing tag.
* @return A string. * @return A string.
* @throws JSONException * @throws JSONException
*/ */
public static String toString(Object object, String tagName) public static String toString(Object object, String tagName)
throws JSONException { throws JSONException {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
int i;
JSONArray ja; JSONArray ja;
JSONObject jo; JSONObject jo;
String key; String key;
Iterator<String> keys; Iterator<String> keys;
int length;
String string; String string;
Object value; Object value;
if (object instanceof JSONObject) { if (object instanceof JSONObject) {
// Emit <tagName> // Emit <tagName>
if (tagName != null) { if (tagName != null) {
sb.append('<'); sb.append('<');
sb.append(tagName); sb.append(tagName);
@@ -398,7 +375,6 @@ public class XML {
} }
// Loop thru the keys. // Loop thru the keys.
jo = (JSONObject) object; jo = (JSONObject) object;
keys = jo.keys(); keys = jo.keys();
while (keys.hasNext()) { while (keys.hasNext()) {
@@ -406,20 +382,22 @@ public class XML {
value = jo.opt(key); value = jo.opt(key);
if (value == null) { if (value == null) {
value = ""; value = "";
} else if (value.getClass().isArray()) {
value = new JSONArray(value);
} }
string = value instanceof String ? (String) value : null; string = value instanceof String ? (String) value : null;
// Emit content in body // Emit content in body
if ("content".equals(key)) { if ("content".equals(key)) {
if (value instanceof JSONArray) { if (value instanceof JSONArray) {
ja = (JSONArray) value; ja = (JSONArray) value;
length = ja.length(); int i = 0;
for (i = 0; i < length; i += 1) { for (Object val : ja) {
if (i > 0) { if (i > 0) {
sb.append('\n'); sb.append('\n');
} }
sb.append(escape(ja.get(i).toString())); sb.append(escape(val.toString()));
i++;
} }
} else { } else {
sb.append(escape(value.toString())); sb.append(escape(value.toString()));
@@ -429,19 +407,17 @@ public class XML {
} else if (value instanceof JSONArray) { } else if (value instanceof JSONArray) {
ja = (JSONArray) value; ja = (JSONArray) value;
length = ja.length(); for (Object val : ja) {
for (i = 0; i < length; i += 1) { if (val instanceof JSONArray) {
value = ja.get(i);
if (value instanceof JSONArray) {
sb.append('<'); sb.append('<');
sb.append(key); sb.append(key);
sb.append('>'); sb.append('>');
sb.append(toString(value)); sb.append(toString(val));
sb.append("</"); sb.append("</");
sb.append(key); sb.append(key);
sb.append('>'); sb.append('>');
} else { } else {
sb.append(toString(value, key)); sb.append(toString(val, key));
} }
} }
} else if ("".equals(value)) { } else if ("".equals(value)) {
@@ -458,17 +434,14 @@ public class XML {
if (tagName != null) { if (tagName != null) {
// Emit the </tagname> close tag // Emit the </tagname> close tag
sb.append("</"); sb.append("</");
sb.append(tagName); sb.append(tagName);
sb.append('>'); sb.append('>');
} }
return sb.toString(); return sb.toString();
// XML does not have good support for arrays. If an array appears in a place
// where XML is lacking, synthesize an <array> element.
} }
if (object != null) { if (object != null) {
if (object.getClass().isArray()) { if (object.getClass().isArray()) {
object = new JSONArray(object); object = new JSONArray(object);
@@ -476,17 +449,20 @@ public class XML {
if (object instanceof JSONArray) { if (object instanceof JSONArray) {
ja = (JSONArray) object; ja = (JSONArray) object;
length = ja.length(); for (Object val : ja) {
for (i = 0; i < length; i += 1) { // XML does not have good support for arrays. If an array
sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName)); // appears in a place where XML is lacking, synthesize an
// <array> element.
sb.append(toString(val, tagName == null ? "array" : tagName));
} }
return sb.toString(); return sb.toString();
} }
} }
string = (object == null) ? "null" : escape(object.toString()); string = (object == null) ? "null" : escape(object.toString());
return (tagName == null) ? "\"" + string + "\"" : return (tagName == null) ? "\"" + string + "\""
(string.length() == 0) ? "<" + tagName + "/>" : : (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName
"<" + tagName + ">" + string + "</" + tagName + ">"; + ">" + string + "</" + tagName + ">";
} }
} }

2
XMLTokener.java Executable file → Normal file
View File

@@ -28,7 +28,7 @@ SOFTWARE.
* The XMLTokener extends the JSONTokener to provide additional methods * The XMLTokener extends the JSONTokener to provide additional methods
* for the parsing of XML texts. * for the parsing of XML texts.
* @author JSON.org * @author JSON.org
* @version 2014-05-03 * @version 2015-12-09
*/ */
public class XMLTokener extends JSONTokener { public class XMLTokener extends JSONTokener {