mirror of
https://github.com/stleary/JSON-java.git
synced 2026-01-24 00:03:17 -05:00
Compare commits
97 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e079599c4 | ||
|
|
3080b8beeb | ||
|
|
2c228ecf1a | ||
|
|
3890bfae52 | ||
|
|
abf2963bbe | ||
|
|
09d37e59b8 | ||
|
|
93704371bb | ||
|
|
42e0944708 | ||
|
|
7627d40d10 | ||
|
|
04181fb6e2 | ||
|
|
239e0b7070 | ||
|
|
a8a71898a3 | ||
|
|
86e8f7b313 | ||
|
|
42791ab12d | ||
|
|
b3abaa5b4c | ||
|
|
eb569b58fc | ||
|
|
16a86d73df | ||
|
|
dfa651e777 | ||
|
|
612dafc750 | ||
|
|
808320801a | ||
|
|
b2bde1f468 | ||
|
|
56be31e7a8 | ||
|
|
9a81b40334 | ||
|
|
4a458a9f1c | ||
|
|
8a72509e6e | ||
|
|
c044eb14dd | ||
|
|
5ae6a66e38 | ||
|
|
d833c2d8de | ||
|
|
f21ffbe189 | ||
|
|
cad23423ab | ||
|
|
ebf08f5651 | ||
|
|
f239dc75ad | ||
|
|
1ca8933a8f | ||
|
|
cbb1546c53 | ||
|
|
c1a789a70c | ||
|
|
bff352791c | ||
|
|
5223aadd67 | ||
|
|
45bd72c15d | ||
|
|
792c6f6a9c | ||
|
|
5bee7e3b45 | ||
|
|
612e41950c | ||
|
|
86cbfbc864 | ||
|
|
25a87975be | ||
|
|
2f3af56535 | ||
|
|
26477f4e76 | ||
|
|
f024b52108 | ||
|
|
2657915293 | ||
|
|
07a0f60b6e | ||
|
|
60349ece54 | ||
|
|
ba2585fe6c | ||
|
|
93c79ca566 | ||
|
|
62486fdea4 | ||
|
|
97f1b2744f | ||
|
|
c2b3f2bdb1 | ||
|
|
3007fc8ebe | ||
|
|
39b1c0cb66 | ||
|
|
07b2d65e30 | ||
|
|
5b67330b71 | ||
|
|
9950350f12 | ||
|
|
2b2fac3eb1 | ||
|
|
e2a0bb16a2 | ||
|
|
a971736f5b | ||
|
|
757fd566ab | ||
|
|
e6f5047742 | ||
|
|
8688494876 | ||
|
|
48302592cf | ||
|
|
03dd662e72 | ||
|
|
23cf659730 | ||
|
|
ec8f649467 | ||
|
|
39e3ccc671 | ||
|
|
2ec538f420 | ||
|
|
cadba9400c | ||
|
|
44275e3b3c | ||
|
|
5f2e77f9dd | ||
|
|
a109f581c8 | ||
|
|
33ae025e78 | ||
|
|
564ad2c2fb | ||
|
|
dfd19116d3 | ||
|
|
105426b53f | ||
|
|
7886c96204 | ||
|
|
91c6f09be8 | ||
|
|
a07d391eae | ||
|
|
e7f4eb5f67 | ||
|
|
b0a9507add | ||
|
|
6757e04c0a | ||
|
|
09b6af4712 | ||
|
|
637c1fe2b9 | ||
|
|
1448163981 | ||
|
|
5ddc515679 | ||
|
|
1b06a802cf | ||
|
|
0e13241528 | ||
|
|
e239e1967a | ||
|
|
ceba8e8c3d | ||
|
|
4e77383472 | ||
|
|
25b5aa7ef2 | ||
|
|
409eb9f292 | ||
|
|
0afd26623c |
7
CDL.java
Executable file → Normal file
7
CDL.java
Executable file → Normal 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 2016-05-01
|
||||||
*/
|
*/
|
||||||
public class CDL {
|
public class CDL {
|
||||||
|
|
||||||
@@ -69,8 +69,13 @@ public class CDL {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
c = x.next();
|
c = x.next();
|
||||||
if (c == q) {
|
if (c == q) {
|
||||||
|
//Handle escaped double-quote
|
||||||
|
if(x.next() != '\"')
|
||||||
|
{
|
||||||
|
x.back();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (c == 0 || c == '\n' || c == '\r') {
|
if (c == 0 || c == '\n' || c == '\r') {
|
||||||
throw x.syntaxError("Missing close quote '" + q + "'.");
|
throw x.syntaxError("Missing close quote '" + q + "'.");
|
||||||
}
|
}
|
||||||
|
|||||||
2
Cookie.java
Executable file → Normal file
2
Cookie.java
Executable file → Normal 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
2
CookieList.java
Executable file → Normal 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
2
HTTP.java
Executable file → Normal 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
2
HTTPTokener.java
Executable file → Normal 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 {
|
||||||
|
|
||||||
|
|||||||
203
JSONArray.java
203
JSONArray.java
@@ -28,10 +28,12 @@ import java.io.IOException;
|
|||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.math.*;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,7 +78,7 @@ import java.util.Map;
|
|||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author JSON.org
|
* @author JSON.org
|
||||||
* @version 2015-07-22
|
* @version 2016-07-19
|
||||||
*/
|
*/
|
||||||
public class JSONArray implements Iterable<Object> {
|
public class JSONArray implements Iterable<Object> {
|
||||||
|
|
||||||
@@ -151,12 +153,11 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @param collection
|
* @param collection
|
||||||
* A Collection.
|
* A Collection.
|
||||||
*/
|
*/
|
||||||
public JSONArray(Collection<Object> collection) {
|
public JSONArray(Collection<?> collection) {
|
||||||
this.myArrayList = new ArrayList<Object>();
|
this.myArrayList = new ArrayList<Object>();
|
||||||
if (collection != null) {
|
if (collection != null) {
|
||||||
Iterator<Object> iter = collection.iterator();
|
for (Object o : collection) {
|
||||||
while (iter.hasNext()) {
|
this.myArrayList.add(JSONObject.wrap(o));
|
||||||
this.myArrayList.add(JSONObject.wrap(iter.next()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,11 +241,15 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
public double getDouble(int index) throws JSONException {
|
public double getDouble(int index) throws JSONException {
|
||||||
Object object = this.get(index);
|
Object object = this.get(index);
|
||||||
try {
|
try {
|
||||||
return object instanceof Number ? ((Number) object).doubleValue()
|
if (object instanceof Number) {
|
||||||
: Double.parseDouble((String) object);
|
return ((Number) object).doubleValue();
|
||||||
} catch (Exception e) {
|
} else if (object instanceof String) {
|
||||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
return Double.parseDouble((String) object);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -324,11 +329,15 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
public int getInt(int index) throws JSONException {
|
public int getInt(int index) throws JSONException {
|
||||||
Object object = this.get(index);
|
Object object = this.get(index);
|
||||||
try {
|
try {
|
||||||
return object instanceof Number ? ((Number) object).intValue()
|
if (object instanceof Number) {
|
||||||
: Integer.parseInt((String) object);
|
return ((Number) object).intValue();
|
||||||
} catch (Exception e) {
|
} else if (object instanceof String) {
|
||||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
return Integer.parseInt((String) object);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -380,11 +389,15 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
public long getLong(int index) throws JSONException {
|
public long getLong(int index) throws JSONException {
|
||||||
Object object = this.get(index);
|
Object object = this.get(index);
|
||||||
try {
|
try {
|
||||||
return object instanceof Number ? ((Number) object).longValue()
|
if (object instanceof Number) {
|
||||||
: Long.parseLong((String) object);
|
return ((Number) object).longValue();
|
||||||
} catch (Exception e) {
|
} else if (object instanceof String) {
|
||||||
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
return Long.parseLong((String) object);
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
throw new JSONException("JSONArray[" + index + "] is not a number.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -485,11 +498,20 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The truth.
|
* @return The truth.
|
||||||
*/
|
*/
|
||||||
public boolean optBoolean(int index, boolean defaultValue) {
|
public boolean optBoolean(int index, boolean defaultValue) {
|
||||||
try {
|
Object object = this.opt(index);
|
||||||
return this.getBoolean(index);
|
if (JSONObject.NULL.equals(object)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
if (object.equals(Boolean.FALSE)
|
||||||
|
|| (object instanceof String && ((String) object)
|
||||||
|
.equalsIgnoreCase("false"))) {
|
||||||
|
return false;
|
||||||
|
} else if (object.equals(Boolean.TRUE)
|
||||||
|
|| (object instanceof String && ((String) object)
|
||||||
|
.equalsIgnoreCase("true"))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -517,11 +539,20 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public double optDouble(int index, double defaultValue) {
|
public double optDouble(int index, double defaultValue) {
|
||||||
try {
|
Object object = this.opt(index);
|
||||||
return this.getDouble(index);
|
if (JSONObject.NULL.equals(object)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
if (object instanceof Number) {
|
||||||
|
return ((Number) object).doubleValue();
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return Double.parseDouble((String) object);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -549,11 +580,20 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public int optInt(int index, int defaultValue) {
|
public int optInt(int index, int defaultValue) {
|
||||||
try {
|
Object object = this.opt(index);
|
||||||
return this.getInt(index);
|
if (JSONObject.NULL.equals(object)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
if (object instanceof Number) {
|
||||||
|
return ((Number) object).intValue();
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return Integer.parseInt((String) object);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -594,7 +634,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -612,8 +654,12 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public BigInteger optBigInteger(int index, BigInteger defaultValue) {
|
public BigInteger optBigInteger(int index, BigInteger defaultValue) {
|
||||||
|
Object object = this.opt(index);
|
||||||
|
if (JSONObject.NULL.equals(object)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return this.getBigInteger(index);
|
return new BigInteger(object.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@@ -631,8 +677,12 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
|
public BigDecimal optBigDecimal(int index, BigDecimal defaultValue) {
|
||||||
|
Object object = this.opt(index);
|
||||||
|
if (JSONObject.NULL.equals(object)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return this.getBigDecimal(index);
|
return new BigDecimal(object.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@@ -690,11 +740,20 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
public long optLong(int index, long defaultValue) {
|
public long optLong(int index, long defaultValue) {
|
||||||
try {
|
Object object = this.opt(index);
|
||||||
return this.getLong(index);
|
if (JSONObject.NULL.equals(object)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
if (object instanceof Number) {
|
||||||
|
return ((Number) object).longValue();
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return Long.parseLong((String) object);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -746,7 +805,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* A Collection value.
|
* A Collection value.
|
||||||
* @return this.
|
* @return this.
|
||||||
*/
|
*/
|
||||||
public JSONArray put(Collection<Object> value) {
|
public JSONArray put(Collection<?> value) {
|
||||||
this.put(new JSONArray(value));
|
this.put(new JSONArray(value));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -799,7 +858,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* A Map value.
|
* A Map value.
|
||||||
* @return this.
|
* @return this.
|
||||||
*/
|
*/
|
||||||
public JSONArray put(Map<String, Object> value) {
|
public JSONArray put(Map<?, ?> value) {
|
||||||
this.put(new JSONObject(value));
|
this.put(new JSONObject(value));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -848,7 +907,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
* If the index is negative or if the value is not finite.
|
* If the index is negative or if the value is not finite.
|
||||||
*/
|
*/
|
||||||
public JSONArray put(int index, Collection<Object> value) throws JSONException {
|
public JSONArray put(int index, Collection<?> value) throws JSONException {
|
||||||
this.put(index, new JSONArray(value));
|
this.put(index, new JSONArray(value));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -920,7 +979,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* If the index is negative or if the the value is an invalid
|
* If the index is negative or if the the value is an invalid
|
||||||
* number.
|
* number.
|
||||||
*/
|
*/
|
||||||
public JSONArray put(int index, Map<String, Object> value) throws JSONException {
|
public JSONArray put(int index, Map<?, ?> value) throws JSONException {
|
||||||
this.put(index, new JSONObject(value));
|
this.put(index, new JSONObject(value));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -957,6 +1016,46 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSONPointer using an initialization string and tries to
|
||||||
|
* match it to an item within this JSONArray. For example, given a
|
||||||
|
* JSONArray initialized with this document:
|
||||||
|
* <pre>
|
||||||
|
* [
|
||||||
|
* {"b":"c"}
|
||||||
|
* ]
|
||||||
|
* </pre>
|
||||||
|
* and this JSONPointer string:
|
||||||
|
* <pre>
|
||||||
|
* "/0/b"
|
||||||
|
* </pre>
|
||||||
|
* Then this method will return the String "c"
|
||||||
|
* A JSONPointerException may be thrown from code called by this method.
|
||||||
|
*
|
||||||
|
* @param jsonPointer string that can be used to create a JSONPointer
|
||||||
|
* @return the item matched by the JSONPointer, otherwise null
|
||||||
|
*/
|
||||||
|
public Object query(String jsonPointer) {
|
||||||
|
return new JSONPointer(jsonPointer).queryFrom(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||||
|
* returns null if the query fails due to a missing key.
|
||||||
|
*
|
||||||
|
* @param jsonPointer the string representation of the JSON pointer
|
||||||
|
* @return the queried value or {@code null}
|
||||||
|
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||||
|
*/
|
||||||
|
public Object optQuery(String jsonPointer) {
|
||||||
|
JSONPointer pointer = new JSONPointer(jsonPointer);
|
||||||
|
try {
|
||||||
|
return pointer.queryFrom(this);
|
||||||
|
} catch (JSONPointerException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an index and close the hole.
|
* Remove an index and close the hole.
|
||||||
*
|
*
|
||||||
@@ -1038,6 +1137,7 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
* @return a printable, displayable, transmittable representation of the
|
* @return a printable, displayable, transmittable representation of the
|
||||||
* array.
|
* array.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
try {
|
try {
|
||||||
return this.toString(0);
|
return this.toString(0);
|
||||||
@@ -1084,6 +1184,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
|
||||||
@@ -1091,7 +1193,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;
|
||||||
@@ -1127,4 +1229,29 @@ public class JSONArray implements Iterable<Object> {
|
|||||||
throw new JSONException(e);
|
throw new JSONException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a java.util.List containing all of the elements in this array.
|
||||||
|
* If an element in the array is a JSONArray or JSONObject it will also
|
||||||
|
* be converted.
|
||||||
|
* <p>
|
||||||
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
*
|
||||||
|
* @return a java.util.List containing the elements of this array
|
||||||
|
*/
|
||||||
|
public List<Object> toList() {
|
||||||
|
List<Object> results = new ArrayList<Object>(this.myArrayList.size());
|
||||||
|
for (Object element : this.myArrayList) {
|
||||||
|
if (element == null || JSONObject.NULL.equals(element)) {
|
||||||
|
results.add(null);
|
||||||
|
} else if (element instanceof JSONArray) {
|
||||||
|
results.add(((JSONArray) element).toList());
|
||||||
|
} else if (element instanceof JSONObject) {
|
||||||
|
results.add(((JSONObject) element).toMap());
|
||||||
|
} else {
|
||||||
|
results.add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
JSONException.java
Executable file → Normal file
32
JSONException.java
Executable file → Normal file
@@ -4,11 +4,11 @@ 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 2014-05-03
|
* @version 2015-12-09
|
||||||
*/
|
*/
|
||||||
public class JSONException extends RuntimeException {
|
public class JSONException extends RuntimeException {
|
||||||
|
/** Serialization ID */
|
||||||
private static final long serialVersionUID = 0;
|
private static final long serialVersionUID = 0;
|
||||||
private Throwable cause;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a JSONException with an explanatory message.
|
* Constructs a JSONException with an explanatory message.
|
||||||
@@ -16,28 +16,30 @@ public class JSONException extends RuntimeException {
|
|||||||
* @param message
|
* @param message
|
||||||
* Detail about the reason for the exception.
|
* Detail about the reason for the exception.
|
||||||
*/
|
*/
|
||||||
public JSONException(String message) {
|
public JSONException(final String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new JSONException with the specified cause.
|
* Constructs a JSONException with an explanatory message and cause.
|
||||||
* @param cause The cause.
|
*
|
||||||
|
* @param message
|
||||||
|
* Detail about the reason for the exception.
|
||||||
|
* @param cause
|
||||||
|
* The cause.
|
||||||
*/
|
*/
|
||||||
public JSONException(Throwable cause) {
|
public JSONException(final String message, final Throwable cause) {
|
||||||
super(cause.getMessage());
|
super(message, cause);
|
||||||
this.cause = cause;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the cause of this exception or null if the cause is nonexistent
|
* Constructs a new JSONException with the specified cause.
|
||||||
* or unknown.
|
|
||||||
*
|
*
|
||||||
* @return the cause of this exception or null if the cause is nonexistent
|
* @param cause
|
||||||
* or unknown.
|
* The cause.
|
||||||
*/
|
*/
|
||||||
@Override
|
public JSONException(final Throwable cause) {
|
||||||
public Throwable getCause() {
|
super(cause.getMessage(), cause);
|
||||||
return this.cause;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
155
JSONML.java
Executable file → Normal file
155
JSONML.java
Executable file → Normal file
@@ -33,23 +33,24 @@ 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 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse XML values and store them in a JSONArray.
|
* Parse XML values and store them in a JSONArray.
|
||||||
* @param x The XMLTokener containing the source string.
|
* @param x The XMLTokener containing the source string.
|
||||||
* @param arrayForm true if array form, false if object form.
|
* @param arrayForm true if array form, false if object form.
|
||||||
* @param ja The JSONArray that is containing the current tag or null
|
* @param ja The JSONArray that is containing the current tag or null
|
||||||
* if we are at the outermost level.
|
* if we are at the outermost level.
|
||||||
|
* @param keepStrings Don't type-convert text nodes and attibute values
|
||||||
* @return A JSONArray if the value is the outermost tag, otherwise null.
|
* @return A JSONArray if the value is the outermost tag, otherwise null.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
private static Object parse(
|
private static Object parse(
|
||||||
XMLTokener x,
|
XMLTokener x,
|
||||||
boolean arrayForm,
|
boolean arrayForm,
|
||||||
JSONArray ja
|
JSONArray ja,
|
||||||
|
boolean keepStrings
|
||||||
) throws JSONException {
|
) throws JSONException {
|
||||||
String attribute;
|
String attribute;
|
||||||
char c;
|
char c;
|
||||||
@@ -174,7 +175,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, keepStrings ? token :JSONObject.stringToValue((String)token));
|
||||||
token = null;
|
token = null;
|
||||||
} else {
|
} else {
|
||||||
newjo.accumulate(attribute, "");
|
newjo.accumulate(attribute, "");
|
||||||
@@ -193,9 +194,8 @@ public class JSONML {
|
|||||||
if (ja == null) {
|
if (ja == null) {
|
||||||
if (arrayForm) {
|
if (arrayForm) {
|
||||||
return newja;
|
return newja;
|
||||||
} else {
|
|
||||||
return newjo;
|
|
||||||
}
|
}
|
||||||
|
return newjo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Content, between <...> and </...>
|
// Content, between <...> and </...>
|
||||||
@@ -204,7 +204,7 @@ public class JSONML {
|
|||||||
if (token != XML.GT) {
|
if (token != XML.GT) {
|
||||||
throw x.syntaxError("Misshaped tag");
|
throw x.syntaxError("Misshaped tag");
|
||||||
}
|
}
|
||||||
closeTag = (String)parse(x, arrayForm, newja);
|
closeTag = (String)parse(x, arrayForm, newja, keepStrings);
|
||||||
if (closeTag != null) {
|
if (closeTag != null) {
|
||||||
if (!closeTag.equals(tagName)) {
|
if (!closeTag.equals(tagName)) {
|
||||||
throw x.syntaxError("Mismatched '" + tagName +
|
throw x.syntaxError("Mismatched '" + tagName +
|
||||||
@@ -217,9 +217,8 @@ public class JSONML {
|
|||||||
if (ja == null) {
|
if (ja == null) {
|
||||||
if (arrayForm) {
|
if (arrayForm) {
|
||||||
return newja;
|
return newja;
|
||||||
} else {
|
|
||||||
return newjo;
|
|
||||||
}
|
}
|
||||||
|
return newjo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,7 +226,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)
|
? keepStrings ? token :JSONObject.stringToValue((String)token)
|
||||||
: token);
|
: token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,10 +244,54 @@ public class JSONML {
|
|||||||
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
||||||
* @param string The source string.
|
* @param string The source string.
|
||||||
* @return A JSONArray containing the structured data from the XML string.
|
* @return A JSONArray containing the structured data from the XML string.
|
||||||
* @throws JSONException
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
*/
|
*/
|
||||||
public static JSONArray toJSONArray(String string) throws JSONException {
|
public static JSONArray toJSONArray(String string) throws JSONException {
|
||||||
return toJSONArray(new XMLTokener(string));
|
return (JSONArray)parse(new XMLTokener(string), true, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a well-formed (but not necessarily valid) XML string into a
|
||||||
|
* JSONArray using the JsonML transform. Each XML tag is represented as
|
||||||
|
* a JSONArray in which the first element is the tag name. If the tag has
|
||||||
|
* attributes, then the second element will be JSONObject containing the
|
||||||
|
* name/value pairs. If the tag contains children, then strings and
|
||||||
|
* JSONArrays will represent the child tags.
|
||||||
|
* As opposed to toJSONArray this method does not attempt to convert
|
||||||
|
* any text node or attribute value to any type
|
||||||
|
* but just leaves it as a string.
|
||||||
|
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
||||||
|
* @param string The source string.
|
||||||
|
* @param keepStrings If true, then values will not be coerced into boolean
|
||||||
|
* or numeric values and will instead be left as strings
|
||||||
|
* @return A JSONArray containing the structured data from the XML string.
|
||||||
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
|
*/
|
||||||
|
public static JSONArray toJSONArray(String string, boolean keepStrings) throws JSONException {
|
||||||
|
return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a well-formed (but not necessarily valid) XML string into a
|
||||||
|
* JSONArray using the JsonML transform. Each XML tag is represented as
|
||||||
|
* a JSONArray in which the first element is the tag name. If the tag has
|
||||||
|
* attributes, then the second element will be JSONObject containing the
|
||||||
|
* name/value pairs. If the tag contains children, then strings and
|
||||||
|
* JSONArrays will represent the child content and tags.
|
||||||
|
* As opposed to toJSONArray this method does not attempt to convert
|
||||||
|
* any text node or attribute value to any type
|
||||||
|
* but just leaves it as a string.
|
||||||
|
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
||||||
|
* @param x An XMLTokener.
|
||||||
|
* @param keepStrings If true, then values will not be coerced into boolean
|
||||||
|
* or numeric values and will instead be left as strings
|
||||||
|
* @return A JSONArray containing the structured data from the XML string.
|
||||||
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
|
*/
|
||||||
|
public static JSONArray toJSONArray(XMLTokener x, boolean keepStrings) throws JSONException {
|
||||||
|
return (JSONArray)parse(x, true, null, keepStrings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -262,28 +305,10 @@ public class JSONML {
|
|||||||
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
||||||
* @param x An XMLTokener.
|
* @param x An XMLTokener.
|
||||||
* @return A JSONArray containing the structured data from the XML string.
|
* @return A JSONArray containing the structured data from the XML string.
|
||||||
* @throws JSONException
|
* @throws JSONException Thrown on error converting to a JSONArray
|
||||||
*/
|
*/
|
||||||
public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
|
public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
|
||||||
return (JSONArray)parse(x, true, null);
|
return (JSONArray)parse(x, true, null, false);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a well-formed (but not necessarily valid) XML string into a
|
|
||||||
* JSONObject using the JsonML transform. Each XML tag is represented as
|
|
||||||
* a JSONObject with a "tagName" property. If the tag has attributes, then
|
|
||||||
* the attributes will be in the JSONObject as properties. If the tag
|
|
||||||
* contains children, the object will have a "childNodes" property which
|
|
||||||
* will be an array of strings and JsonML JSONObjects.
|
|
||||||
|
|
||||||
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
|
||||||
* @param x An XMLTokener of the XML source text.
|
|
||||||
* @return A JSONObject containing the structured data from the XML string.
|
|
||||||
* @throws JSONException
|
|
||||||
*/
|
|
||||||
public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
|
|
||||||
return (JSONObject)parse(x, false, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -298,10 +323,68 @@ public class JSONML {
|
|||||||
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
||||||
* @param string The XML source text.
|
* @param string The XML source text.
|
||||||
* @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 Thrown on error converting to a JSONObject
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(String string) throws JSONException {
|
public static JSONObject toJSONObject(String string) throws JSONException {
|
||||||
return toJSONObject(new XMLTokener(string));
|
return (JSONObject)parse(new XMLTokener(string), false, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a well-formed (but not necessarily valid) XML string into a
|
||||||
|
* JSONObject using the JsonML transform. Each XML tag is represented as
|
||||||
|
* a JSONObject with a "tagName" property. If the tag has attributes, then
|
||||||
|
* the attributes will be in the JSONObject as properties. If the tag
|
||||||
|
* contains children, the object will have a "childNodes" property which
|
||||||
|
* will be an array of strings and JsonML JSONObjects.
|
||||||
|
|
||||||
|
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
||||||
|
* @param string The XML source text.
|
||||||
|
* @param keepStrings If true, then values will not be coerced into boolean
|
||||||
|
* or numeric values and will instead be left as strings
|
||||||
|
* @return A JSONObject containing the structured data from the XML string.
|
||||||
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
|
*/
|
||||||
|
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
|
||||||
|
return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a well-formed (but not necessarily valid) XML string into a
|
||||||
|
* JSONObject using the JsonML transform. Each XML tag is represented as
|
||||||
|
* a JSONObject with a "tagName" property. If the tag has attributes, then
|
||||||
|
* the attributes will be in the JSONObject as properties. If the tag
|
||||||
|
* contains children, the object will have a "childNodes" property which
|
||||||
|
* will be an array of strings and JsonML JSONObjects.
|
||||||
|
|
||||||
|
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
||||||
|
* @param x An XMLTokener of the XML source text.
|
||||||
|
* @return A JSONObject containing the structured data from the XML string.
|
||||||
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
|
*/
|
||||||
|
public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
|
||||||
|
return (JSONObject)parse(x, false, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a well-formed (but not necessarily valid) XML string into a
|
||||||
|
* JSONObject using the JsonML transform. Each XML tag is represented as
|
||||||
|
* a JSONObject with a "tagName" property. If the tag has attributes, then
|
||||||
|
* the attributes will be in the JSONObject as properties. If the tag
|
||||||
|
* contains children, the object will have a "childNodes" property which
|
||||||
|
* will be an array of strings and JsonML JSONObjects.
|
||||||
|
|
||||||
|
* Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
|
||||||
|
* @param x An XMLTokener of the XML source text.
|
||||||
|
* @param keepStrings If true, then values will not be coerced into boolean
|
||||||
|
* or numeric values and will instead be left as strings
|
||||||
|
* @return A JSONObject containing the structured data from the XML string.
|
||||||
|
* @throws JSONException Thrown on error converting to a JSONObject
|
||||||
|
*/
|
||||||
|
public static JSONObject toJSONObject(XMLTokener x, boolean keepStrings) throws JSONException {
|
||||||
|
return (JSONObject)parse(x, false, null, keepStrings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -309,7 +392,7 @@ public class JSONML {
|
|||||||
* Reverse the JSONML transformation, making an XML text from a JSONArray.
|
* Reverse the JSONML transformation, making an XML text from a JSONArray.
|
||||||
* @param ja A JSONArray.
|
* @param ja A JSONArray.
|
||||||
* @return An XML string.
|
* @return An XML string.
|
||||||
* @throws JSONException
|
* @throws JSONException Thrown on error converting to a string
|
||||||
*/
|
*/
|
||||||
public static String toString(JSONArray ja) throws JSONException {
|
public static String toString(JSONArray ja) throws JSONException {
|
||||||
int i;
|
int i;
|
||||||
@@ -393,7 +476,7 @@ public class JSONML {
|
|||||||
* The other properties are attributes with string values.
|
* The other properties are attributes with string values.
|
||||||
* @param jo A JSONObject.
|
* @param jo A JSONObject.
|
||||||
* @return An XML string.
|
* @return An XML string.
|
||||||
* @throws JSONException
|
* @throws JSONException Thrown on error converting to a string
|
||||||
*/
|
*/
|
||||||
public static String toString(JSONObject jo) throws JSONException {
|
public static String toString(JSONObject jo) throws JSONException {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|||||||
250
JSONObject.java
Executable file → Normal file
250
JSONObject.java
Executable file → Normal 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-07-22
|
* @version 2016-07-19
|
||||||
*/
|
*/
|
||||||
public class JSONObject {
|
public class JSONObject {
|
||||||
/**
|
/**
|
||||||
@@ -131,6 +132,7 @@ public class JSONObject {
|
|||||||
*
|
*
|
||||||
* @return The string "null".
|
* @return The string "null".
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "null";
|
return "null";
|
||||||
}
|
}
|
||||||
@@ -165,10 +167,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,17 +239,14 @@ 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<String, Object> map) {
|
public JSONObject(Map<?, ?> map) {
|
||||||
this.map = new HashMap<String, Object>();
|
this.map = new HashMap<String, Object>();
|
||||||
if (map != null) {
|
if (map != null) {
|
||||||
Iterator<Entry<String, Object>> i = map.entrySet().iterator();
|
for (final Entry<?, ?> e : map.entrySet()) {
|
||||||
while (i.hasNext()) {
|
final Object value = e.getValue();
|
||||||
Entry<String, Object> entry = i.next();
|
|
||||||
Object value = entry.getValue();
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
this.map.put(entry.getKey(), wrap(value));
|
this.map.put(String.valueOf(e.getKey()), wrap(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -582,13 +577,16 @@ public class JSONObject {
|
|||||||
public double getDouble(String key) throws JSONException {
|
public double getDouble(String key) throws JSONException {
|
||||||
Object object = this.get(key);
|
Object object = this.get(key);
|
||||||
try {
|
try {
|
||||||
return object instanceof Number ? ((Number) object).doubleValue()
|
if (object instanceof Number) {
|
||||||
: Double.parseDouble((String) object);
|
return ((Number) object).doubleValue();
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return Double.parseDouble((String) object);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
throw new JSONException("JSONObject[" + quote(key)
|
throw new JSONException("JSONObject[" + quote(key)
|
||||||
+ "] is not a number.");
|
+ "] is not a number.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the int value associated with a key.
|
* Get the int value associated with a key.
|
||||||
@@ -603,12 +601,15 @@ public class JSONObject {
|
|||||||
public int getInt(String key) throws JSONException {
|
public int getInt(String key) throws JSONException {
|
||||||
Object object = this.get(key);
|
Object object = this.get(key);
|
||||||
try {
|
try {
|
||||||
return object instanceof Number ? ((Number) object).intValue()
|
if (object instanceof Number) {
|
||||||
: Integer.parseInt((String) object);
|
return ((Number) object).intValue();
|
||||||
} catch (Exception e) {
|
} else if (object instanceof String) {
|
||||||
throw new JSONException("JSONObject[" + quote(key)
|
return Integer.parseInt((String) object);
|
||||||
+ "] is not an int.");
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
throw new JSONException("JSONObject[" + quote(key) + "] is not an int.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -660,12 +661,15 @@ public class JSONObject {
|
|||||||
public long getLong(String key) throws JSONException {
|
public long getLong(String key) throws JSONException {
|
||||||
Object object = this.get(key);
|
Object object = this.get(key);
|
||||||
try {
|
try {
|
||||||
return object instanceof Number ? ((Number) object).longValue()
|
if (object instanceof Number) {
|
||||||
: Long.parseLong((String) object);
|
return ((Number) object).longValue();
|
||||||
} catch (Exception e) {
|
} else if (object instanceof String) {
|
||||||
throw new JSONException("JSONObject[" + quote(key)
|
return Long.parseLong((String) object);
|
||||||
+ "] is not a long.");
|
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
throw new JSONException("JSONObject[" + quote(key) + "] is not a long.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -907,7 +911,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -936,11 +942,20 @@ public class JSONObject {
|
|||||||
* @return The truth.
|
* @return The truth.
|
||||||
*/
|
*/
|
||||||
public boolean optBoolean(String key, boolean defaultValue) {
|
public boolean optBoolean(String key, boolean defaultValue) {
|
||||||
try {
|
Object object = this.get(key);
|
||||||
return this.getBoolean(key);
|
if (NULL.equals(object)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
if (object.equals(Boolean.FALSE)
|
||||||
|
|| (object instanceof String && ((String) object)
|
||||||
|
.equalsIgnoreCase("false"))) {
|
||||||
|
return false;
|
||||||
|
} else if (object.equals(Boolean.TRUE)
|
||||||
|
|| (object instanceof String && ((String) object)
|
||||||
|
.equalsIgnoreCase("true"))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -968,8 +983,12 @@ public class JSONObject {
|
|||||||
* @return An object which is the value.
|
* @return An object which is the value.
|
||||||
*/
|
*/
|
||||||
public BigInteger optBigInteger(String key, BigInteger defaultValue) {
|
public BigInteger optBigInteger(String key, BigInteger defaultValue) {
|
||||||
|
Object object = this.get(key);
|
||||||
|
if (NULL.equals(object)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return this.getBigInteger(key);
|
return new BigInteger(object.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@@ -987,8 +1006,12 @@ public class JSONObject {
|
|||||||
* @return An object which is the value.
|
* @return An object which is the value.
|
||||||
*/
|
*/
|
||||||
public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
|
public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) {
|
||||||
|
Object object = this.opt(key);
|
||||||
|
if (NULL.equals(object)) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return this.getBigDecimal(key);
|
return new BigDecimal(object.toString());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
@@ -1006,11 +1029,20 @@ public class JSONObject {
|
|||||||
* @return An object which is the value.
|
* @return An object which is the value.
|
||||||
*/
|
*/
|
||||||
public double optDouble(String key, double defaultValue) {
|
public double optDouble(String key, double defaultValue) {
|
||||||
try {
|
Object object = this.get(key);
|
||||||
return this.getDouble(key);
|
if (NULL.equals(object)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
if (object instanceof Number) {
|
||||||
|
return ((Number) object).doubleValue();
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return Double.parseDouble((String) object);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1038,11 +1070,20 @@ public class JSONObject {
|
|||||||
* @return An object which is the value.
|
* @return An object which is the value.
|
||||||
*/
|
*/
|
||||||
public int optInt(String key, int defaultValue) {
|
public int optInt(String key, int defaultValue) {
|
||||||
try {
|
Object object = this.get(key);
|
||||||
return this.getInt(key);
|
if (NULL.equals(object)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
if (object instanceof Number) {
|
||||||
|
return ((Number) object).intValue();
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return Integer.parseInt((String) object);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1096,11 +1137,20 @@ public class JSONObject {
|
|||||||
* @return An object which is the value.
|
* @return An object which is the value.
|
||||||
*/
|
*/
|
||||||
public long optLong(String key, long defaultValue) {
|
public long optLong(String key, long defaultValue) {
|
||||||
try {
|
Object object = this.get(key);
|
||||||
return this.getLong(key);
|
if (NULL.equals(object)) {
|
||||||
} catch (Exception e) {
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
if (object instanceof Number) {
|
||||||
|
return ((Number) object).longValue();
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
return Long.parseLong((String) object);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1204,7 +1254,7 @@ public class JSONObject {
|
|||||||
* @return this.
|
* @return this.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
public JSONObject put(String key, Collection<Object> value) throws JSONException {
|
public JSONObject put(String key, Collection<?> value) throws JSONException {
|
||||||
this.put(key, new JSONArray(value));
|
this.put(key, new JSONArray(value));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -1268,7 +1318,7 @@ public class JSONObject {
|
|||||||
* @return this.
|
* @return this.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
*/
|
*/
|
||||||
public JSONObject put(String key, Map<String, Object> value) throws JSONException {
|
public JSONObject put(String key, Map<?, ?> value) throws JSONException {
|
||||||
this.put(key, new JSONObject(value));
|
this.put(key, new JSONObject(value));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -1342,6 +1392,46 @@ public class JSONObject {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSONPointer using an intialization string and tries to
|
||||||
|
* match it to an item within this JSONObject. For example, given a
|
||||||
|
* JSONObject initialized with this document:
|
||||||
|
* <pre>
|
||||||
|
* {
|
||||||
|
* "a":{"b":"c"}
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* and this JSONPointer string:
|
||||||
|
* <pre>
|
||||||
|
* "/a/b"
|
||||||
|
* </pre>
|
||||||
|
* Then this method will return the String "c".
|
||||||
|
* A JSONPointerException may be thrown from code called by this method.
|
||||||
|
*
|
||||||
|
* @param jsonPointer string that can be used to create a JSONPointer
|
||||||
|
* @return the item matched by the JSONPointer, otherwise null
|
||||||
|
*/
|
||||||
|
public Object query(String jsonPointer) {
|
||||||
|
return new JSONPointer(jsonPointer).queryFrom(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||||
|
* returns null if the query fails due to a missing key.
|
||||||
|
*
|
||||||
|
* @param jsonPointer the string representation of the JSON pointer
|
||||||
|
* @return the queried value or {@code null}
|
||||||
|
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||||
|
*/
|
||||||
|
public Object optQuery(String jsonPointer) {
|
||||||
|
JSONPointer pointer = new JSONPointer(jsonPointer);
|
||||||
|
try {
|
||||||
|
return pointer.queryFrom(this);
|
||||||
|
} catch (JSONPointerException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Produce a string in double quotes with backslash sequences in all the
|
* Produce a string in double quotes with backslash sequences in all the
|
||||||
* right places. A backslash will be inserted within </, producing <\/,
|
* right places. A backslash will be inserted within </, producing <\/,
|
||||||
@@ -1484,7 +1574,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;
|
||||||
}
|
}
|
||||||
@@ -1503,23 +1592,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) {
|
||||||
@@ -1586,6 +1675,7 @@ public class JSONObject {
|
|||||||
* brace)</small> and ending with <code>}</code> <small>(right
|
* brace)</small> and ending with <code>}</code> <small>(right
|
||||||
* brace)</small>.
|
* brace)</small>.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
try {
|
try {
|
||||||
return this.toString(0);
|
return this.toString(0);
|
||||||
@@ -1663,13 +1753,11 @@ public class JSONObject {
|
|||||||
return value.toString();
|
return value.toString();
|
||||||
}
|
}
|
||||||
if (value instanceof Map) {
|
if (value instanceof Map) {
|
||||||
@SuppressWarnings("unchecked")
|
Map<?, ?> map = (Map<?, ?>) value;
|
||||||
Map<String, Object> map = (Map<String, Object>) value;
|
|
||||||
return new JSONObject(map).toString();
|
return new JSONObject(map).toString();
|
||||||
}
|
}
|
||||||
if (value instanceof Collection) {
|
if (value instanceof Collection) {
|
||||||
@SuppressWarnings("unchecked")
|
Collection<?> coll = (Collection<?>) value;
|
||||||
Collection<Object> coll = (Collection<Object>) value;
|
|
||||||
return new JSONArray(coll).toString();
|
return new JSONArray(coll).toString();
|
||||||
}
|
}
|
||||||
if (value.getClass().isArray()) {
|
if (value.getClass().isArray()) {
|
||||||
@@ -1707,16 +1795,14 @@ public class JSONObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (object instanceof Collection) {
|
if (object instanceof Collection) {
|
||||||
@SuppressWarnings("unchecked")
|
Collection<?> coll = (Collection<?>) object;
|
||||||
Collection<Object> coll = (Collection<Object>) object;
|
|
||||||
return new JSONArray(coll);
|
return new JSONArray(coll);
|
||||||
}
|
}
|
||||||
if (object.getClass().isArray()) {
|
if (object.getClass().isArray()) {
|
||||||
return new JSONArray(object);
|
return new JSONArray(object);
|
||||||
}
|
}
|
||||||
if (object instanceof Map) {
|
if (object instanceof Map) {
|
||||||
@SuppressWarnings("unchecked")
|
Map<?, ?> map = (Map<?, ?>) object;
|
||||||
Map<String, Object> map = (Map<String, Object>) object;
|
|
||||||
return new JSONObject(map);
|
return new JSONObject(map);
|
||||||
}
|
}
|
||||||
Package objectPackage = object.getClass().getPackage();
|
Package objectPackage = object.getClass().getPackage();
|
||||||
@@ -1755,14 +1841,11 @@ public class JSONObject {
|
|||||||
} else if (value instanceof JSONArray) {
|
} else if (value instanceof JSONArray) {
|
||||||
((JSONArray) value).write(writer, indentFactor, indent);
|
((JSONArray) value).write(writer, indentFactor, indent);
|
||||||
} else if (value instanceof Map) {
|
} else if (value instanceof Map) {
|
||||||
@SuppressWarnings("unchecked")
|
Map<?, ?> map = (Map<?, ?>) value;
|
||||||
Map<String, Object> map = (Map<String, Object>) value;
|
|
||||||
new JSONObject(map).write(writer, indentFactor, indent);
|
new JSONObject(map).write(writer, indentFactor, indent);
|
||||||
} else if (value instanceof Collection) {
|
} else if (value instanceof Collection) {
|
||||||
@SuppressWarnings("unchecked")
|
Collection<?> coll = (Collection<?>) value;
|
||||||
Collection<Object> coll = (Collection<Object>) value;
|
new JSONArray(coll).write(writer, indentFactor, indent);
|
||||||
new JSONArray(coll).write(writer, indentFactor,
|
|
||||||
indent);
|
|
||||||
} else if (value.getClass().isArray()) {
|
} else if (value.getClass().isArray()) {
|
||||||
new JSONArray(value).write(writer, indentFactor, indent);
|
new JSONArray(value).write(writer, indentFactor, indent);
|
||||||
} else if (value instanceof Number) {
|
} else if (value instanceof Number) {
|
||||||
@@ -1795,10 +1878,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;
|
||||||
@@ -1844,4 +1933,31 @@ public class JSONObject {
|
|||||||
throw new JSONException(exception);
|
throw new JSONException(exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a java.util.Map containing all of the entries in this object.
|
||||||
|
* If an entry in the object is a JSONArray or JSONObject it will also
|
||||||
|
* be converted.
|
||||||
|
* <p>
|
||||||
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
*
|
||||||
|
* @return a java.util.Map containing the entries of this object
|
||||||
|
*/
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
Map<String, Object> results = new HashMap<String, Object>();
|
||||||
|
for (Entry<String, Object> entry : this.map.entrySet()) {
|
||||||
|
Object value;
|
||||||
|
if (entry.getValue() == null || NULL.equals(entry.getValue())) {
|
||||||
|
value = null;
|
||||||
|
} else if (entry.getValue() instanceof JSONObject) {
|
||||||
|
value = ((JSONObject) entry.getValue()).toMap();
|
||||||
|
} else if (entry.getValue() instanceof JSONArray) {
|
||||||
|
value = ((JSONArray) entry.getValue()).toList();
|
||||||
|
} else {
|
||||||
|
value = entry.getValue();
|
||||||
|
}
|
||||||
|
results.put(entry.getKey(), value);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
267
JSONPointer.java
Normal file
267
JSONPointer.java
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
package org.json;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2002 JSON.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
The Software shall be used for Good, not Evil.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A JSON Pointer is a simple query language defined for JSON documents by
|
||||||
|
* <a href="https://tools.ietf.org/html/rfc6901">RFC 6901</a>.
|
||||||
|
*
|
||||||
|
* In a nutshell, JSONPointer allows the user to navigate into a JSON document
|
||||||
|
* using strings, and retrieve targeted objects, like a simple form of XPATH.
|
||||||
|
* Path segments are separated by the '/' char, which signifies the root of
|
||||||
|
* the document when it appears as the first char of the string. Array
|
||||||
|
* elements are navigated using ordinals, counting from 0. JSONPointer strings
|
||||||
|
* may be extended to any arbitrary number of segments. If the navigation
|
||||||
|
* is successful, the matched item is returned. A matched item may be a
|
||||||
|
* JSONObject, a JSONArray, or a JSON value. If the JSONPointer string building
|
||||||
|
* fails, an appropriate exception is thrown. If the navigation fails to find
|
||||||
|
* a match, a JSONPointerException is thrown.
|
||||||
|
*
|
||||||
|
* @author JSON.org
|
||||||
|
* @version 2016-05-14
|
||||||
|
*/
|
||||||
|
public class JSONPointer {
|
||||||
|
|
||||||
|
// used for URL encoding and decoding
|
||||||
|
private static final String ENCODING = "utf-8";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class allows the user to build a JSONPointer in steps, using
|
||||||
|
* exactly one segment in each step.
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
// Segments for the eventual JSONPointer string
|
||||||
|
private final List<String> refTokens = new ArrayList<String>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@code JSONPointer} instance using the tokens previously set using the
|
||||||
|
* {@link #append(String)} method calls.
|
||||||
|
*/
|
||||||
|
public JSONPointer build() {
|
||||||
|
return new JSONPointer(refTokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an arbitary token to the list of reference tokens. It can be any non-null value.
|
||||||
|
*
|
||||||
|
* Unlike in the case of JSON string or URI fragment representation of JSON pointers, the
|
||||||
|
* argument of this method MUST NOT be escaped. If you want to query the property called
|
||||||
|
* {@code "a~b"} then you should simply pass the {@code "a~b"} string as-is, there is no
|
||||||
|
* need to escape it as {@code "a~0b"}.
|
||||||
|
*
|
||||||
|
* @param token the new token to be appended to the list
|
||||||
|
* @return {@code this}
|
||||||
|
* @throws NullPointerException if {@code token} is null
|
||||||
|
*/
|
||||||
|
public Builder append(String token) {
|
||||||
|
if (token == null) {
|
||||||
|
throw new NullPointerException("token cannot be null");
|
||||||
|
}
|
||||||
|
refTokens.add(token);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an integer to the reference token list. Although not necessarily, mostly this token will
|
||||||
|
* denote an array index.
|
||||||
|
*
|
||||||
|
* @param arrayIndex the array index to be added to the token list
|
||||||
|
* @return {@code this}
|
||||||
|
*/
|
||||||
|
public Builder append(int arrayIndex) {
|
||||||
|
refTokens.add(String.valueOf(arrayIndex));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static factory method for {@link Builder}. Example usage:
|
||||||
|
*
|
||||||
|
* <pre><code>
|
||||||
|
* JSONPointer pointer = JSONPointer.builder()
|
||||||
|
* .append("obj")
|
||||||
|
* .append("other~key").append("another/key")
|
||||||
|
* .append("\"")
|
||||||
|
* .append(0)
|
||||||
|
* .build();
|
||||||
|
* </code></pre>
|
||||||
|
*
|
||||||
|
* @return a builder instance which can be used to construct a {@code JSONPointer} instance by chained
|
||||||
|
* {@link Builder#append(String)} calls.
|
||||||
|
*/
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Segments for the JSONPointer string
|
||||||
|
private final List<String> refTokens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-parses and initializes a new {@code JSONPointer} instance. If you want to
|
||||||
|
* evaluate the same JSON Pointer on different JSON documents then it is recommended
|
||||||
|
* to keep the {@code JSONPointer} instances due to performance considerations.
|
||||||
|
*
|
||||||
|
* @param pointer the JSON String or URI Fragment representation of the JSON pointer.
|
||||||
|
* @throws IllegalArgumentException if {@code pointer} is not a valid JSON pointer
|
||||||
|
*/
|
||||||
|
public JSONPointer(String pointer) {
|
||||||
|
if (pointer == null) {
|
||||||
|
throw new NullPointerException("pointer cannot be null");
|
||||||
|
}
|
||||||
|
if (pointer.isEmpty()) {
|
||||||
|
refTokens = Collections.emptyList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pointer.startsWith("#/")) {
|
||||||
|
pointer = pointer.substring(2);
|
||||||
|
try {
|
||||||
|
pointer = URLDecoder.decode(pointer, ENCODING);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
} else if (pointer.startsWith("/")) {
|
||||||
|
pointer = pointer.substring(1);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("a JSON pointer should start with '/' or '#/'");
|
||||||
|
}
|
||||||
|
refTokens = new ArrayList<String>();
|
||||||
|
for (String token : pointer.split("/")) {
|
||||||
|
refTokens.add(unescape(token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONPointer(List<String> refTokens) {
|
||||||
|
this.refTokens = new ArrayList<String>(refTokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String unescape(String token) {
|
||||||
|
return token.replace("~1", "/").replace("~0", "~")
|
||||||
|
.replace("\\\"", "\"")
|
||||||
|
.replace("\\\\", "\\");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates this JSON Pointer on the given {@code document}. The {@code document}
|
||||||
|
* is usually a {@link JSONObject} or a {@link JSONArray} instance, but the empty
|
||||||
|
* JSON Pointer ({@code ""}) can be evaluated on any JSON values and in such case the
|
||||||
|
* returned value will be {@code document} itself.
|
||||||
|
*
|
||||||
|
* @param document the JSON document which should be the subject of querying.
|
||||||
|
* @return the result of the evaluation
|
||||||
|
* @throws JSONPointerException if an error occurs during evaluation
|
||||||
|
*/
|
||||||
|
public Object queryFrom(Object document) {
|
||||||
|
if (refTokens.isEmpty()) {
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
Object current = document;
|
||||||
|
for (String token : refTokens) {
|
||||||
|
if (current instanceof JSONObject) {
|
||||||
|
current = ((JSONObject) current).opt(unescape(token));
|
||||||
|
} else if (current instanceof JSONArray) {
|
||||||
|
current = readByIndexToken(current, token);
|
||||||
|
} else {
|
||||||
|
throw new JSONPointerException(format(
|
||||||
|
"value [%s] is not an array or object therefore its key %s cannot be resolved", current,
|
||||||
|
token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches a JSONArray element by ordinal position
|
||||||
|
* @param current the JSONArray to be evaluated
|
||||||
|
* @param indexToken the array index in string form
|
||||||
|
* @return the matched object. If no matching item is found a
|
||||||
|
* JSONPointerException is thrown
|
||||||
|
*/
|
||||||
|
private Object readByIndexToken(Object current, String indexToken) {
|
||||||
|
try {
|
||||||
|
int index = Integer.parseInt(indexToken);
|
||||||
|
JSONArray currentArr = (JSONArray) current;
|
||||||
|
if (index >= currentArr.length()) {
|
||||||
|
throw new JSONPointerException(format("index %d is out of bounds - the array has %d elements", index,
|
||||||
|
currentArr.length()));
|
||||||
|
}
|
||||||
|
return currentArr.get(index);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new JSONPointerException(format("%s is not an array index", indexToken), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representing the JSONPointer path value using string
|
||||||
|
* representation
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder rval = new StringBuilder("");
|
||||||
|
for (String token: refTokens) {
|
||||||
|
rval.append('/').append(escape(token));
|
||||||
|
}
|
||||||
|
return rval.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes path segment values to an unambiguous form.
|
||||||
|
* The escape char to be inserted is '~'. The chars to be escaped
|
||||||
|
* are ~, which maps to ~0, and /, which maps to ~1. Backslashes
|
||||||
|
* and double quote chars are also escaped.
|
||||||
|
* @param token the JSONPointer segment value to be escaped
|
||||||
|
* @return the escaped value for the token
|
||||||
|
*/
|
||||||
|
private String escape(String token) {
|
||||||
|
return token.replace("~", "~0")
|
||||||
|
.replace("/", "~1")
|
||||||
|
.replace("\\", "\\\\")
|
||||||
|
.replace("\"", "\\\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representing the JSONPointer path value using URI
|
||||||
|
* fragment identifier representation
|
||||||
|
*/
|
||||||
|
public String toURIFragment() {
|
||||||
|
try {
|
||||||
|
StringBuilder rval = new StringBuilder("#");
|
||||||
|
for (String token : refTokens) {
|
||||||
|
rval.append('/').append(URLEncoder.encode(token, ENCODING));
|
||||||
|
}
|
||||||
|
return rval.toString();
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
45
JSONPointerException.java
Normal file
45
JSONPointerException.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package org.json;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright (c) 2002 JSON.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
The Software shall be used for Good, not Evil.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The JSONPointerException is thrown by {@link JSONPointer} if an error occurs
|
||||||
|
* during evaluating a pointer.
|
||||||
|
*
|
||||||
|
* @author JSON.org
|
||||||
|
* @version 2016-05-13
|
||||||
|
*/
|
||||||
|
public class JSONPointerException extends JSONException {
|
||||||
|
private static final long serialVersionUID = 8872944667561856751L;
|
||||||
|
|
||||||
|
public JSONPointerException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONPointerException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
0
JSONString.java
Executable file → Normal file
0
JSONString.java
Executable file → Normal file
2
JSONStringer.java
Executable file → Normal file
2
JSONStringer.java
Executable file → Normal 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 {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class JSONTokener {
|
|||||||
* Construct a JSONTokener from an InputStream.
|
* Construct a JSONTokener from an InputStream.
|
||||||
* @param inputStream The source.
|
* @param inputStream The source.
|
||||||
*/
|
*/
|
||||||
public JSONTokener(InputStream inputStream) throws JSONException {
|
public JSONTokener(InputStream inputStream) {
|
||||||
this(new InputStreamReader(inputStream));
|
this(new InputStreamReader(inputStream));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +90,8 @@ public class JSONTokener {
|
|||||||
* Back up one character. This provides a sort of lookahead capability,
|
* Back up one character. This provides a sort of lookahead capability,
|
||||||
* so that you can test for a digit or letter before attempting to parse
|
* so that you can test for a digit or letter before attempting to parse
|
||||||
* the next number or identifier.
|
* the next number or identifier.
|
||||||
|
* @throws JSONException Thrown if trying to step back more than 1 step
|
||||||
|
* or if already at the start of the string
|
||||||
*/
|
*/
|
||||||
public void back() throws JSONException {
|
public void back() throws JSONException {
|
||||||
if (this.usePrevious || this.index <= 0) {
|
if (this.usePrevious || this.index <= 0) {
|
||||||
@@ -121,6 +123,9 @@ public class JSONTokener {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if at the end of the file and we didn't step back
|
||||||
|
*/
|
||||||
public boolean end() {
|
public boolean end() {
|
||||||
return this.eof && !this.usePrevious;
|
return this.eof && !this.usePrevious;
|
||||||
}
|
}
|
||||||
@@ -130,6 +135,8 @@ public class JSONTokener {
|
|||||||
* Determine if the source string still contains characters that next()
|
* Determine if the source string still contains characters that next()
|
||||||
* can consume.
|
* can consume.
|
||||||
* @return true if not yet at the end of the source.
|
* @return true if not yet at the end of the source.
|
||||||
|
* @throws JSONException thrown if there is an error stepping forward
|
||||||
|
* or backward while checking for more data.
|
||||||
*/
|
*/
|
||||||
public boolean more() throws JSONException {
|
public boolean more() throws JSONException {
|
||||||
this.next();
|
this.next();
|
||||||
@@ -145,6 +152,7 @@ public class JSONTokener {
|
|||||||
* Get the next character in the source string.
|
* Get the next character in the source string.
|
||||||
*
|
*
|
||||||
* @return The next character, or 0 if past the end of the source string.
|
* @return The next character, or 0 if past the end of the source string.
|
||||||
|
* @throws JSONException Thrown if there is an error reading the source string.
|
||||||
*/
|
*/
|
||||||
public char next() throws JSONException {
|
public char next() throws JSONException {
|
||||||
int c;
|
int c;
|
||||||
@@ -225,7 +233,7 @@ public class JSONTokener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next char in the string, skipping whitespace.
|
* Get the next char in the string, skipping whitespace.
|
||||||
* @throws JSONException
|
* @throws JSONException Thrown if there is an error reading the source string.
|
||||||
* @return A character, or 0 if there are no more characters.
|
* @return A character, or 0 if there are no more characters.
|
||||||
*/
|
*/
|
||||||
public char nextClean() throws JSONException {
|
public char nextClean() throws JSONException {
|
||||||
@@ -278,7 +286,11 @@ public class JSONTokener {
|
|||||||
sb.append('\r');
|
sb.append('\r');
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
|
try {
|
||||||
sb.append((char)Integer.parseInt(this.next(4), 16));
|
sb.append((char)Integer.parseInt(this.next(4), 16));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw this.syntaxError("Illegal escape.", e);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
case '\'':
|
case '\'':
|
||||||
@@ -305,6 +317,8 @@ public class JSONTokener {
|
|||||||
* end of line, whichever comes first.
|
* end of line, whichever comes first.
|
||||||
* @param delimiter A delimiter character.
|
* @param delimiter A delimiter character.
|
||||||
* @return A string.
|
* @return A string.
|
||||||
|
* @throws JSONException Thrown if there is an error while searching
|
||||||
|
* for the delimiter
|
||||||
*/
|
*/
|
||||||
public String nextTo(char delimiter) throws JSONException {
|
public String nextTo(char delimiter) throws JSONException {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@@ -326,6 +340,8 @@ public class JSONTokener {
|
|||||||
* characters or the end of line, whichever comes first.
|
* characters or the end of line, whichever comes first.
|
||||||
* @param delimiters A set of delimiter characters.
|
* @param delimiters A set of delimiter characters.
|
||||||
* @return A string, trimmed.
|
* @return A string, trimmed.
|
||||||
|
* @throws JSONException Thrown if there is an error while searching
|
||||||
|
* for the delimiter
|
||||||
*/
|
*/
|
||||||
public String nextTo(String delimiters) throws JSONException {
|
public String nextTo(String delimiters) throws JSONException {
|
||||||
char c;
|
char c;
|
||||||
@@ -397,6 +413,8 @@ public class JSONTokener {
|
|||||||
* @param to A character to skip to.
|
* @param to A character to skip to.
|
||||||
* @return The requested character, or zero if the requested character
|
* @return The requested character, or zero if the requested character
|
||||||
* is not found.
|
* is not found.
|
||||||
|
* @throws JSONException Thrown if there is an error while searching
|
||||||
|
* for the to character
|
||||||
*/
|
*/
|
||||||
public char skipTo(char to) throws JSONException {
|
public char skipTo(char to) throws JSONException {
|
||||||
char c;
|
char c;
|
||||||
@@ -433,12 +451,23 @@ public class JSONTokener {
|
|||||||
return new JSONException(message + this.toString());
|
return new JSONException(message + this.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make a JSONException to signal a syntax error.
|
||||||
|
*
|
||||||
|
* @param message The error message.
|
||||||
|
* @param causedBy The throwable that caused the error.
|
||||||
|
* @return A JSONException object, suitable for throwing
|
||||||
|
*/
|
||||||
|
public JSONException syntaxError(String message, Throwable causedBy) {
|
||||||
|
return new JSONException(message + this.toString(), causedBy);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a printable string of this JSONTokener.
|
* Make a printable string of this JSONTokener.
|
||||||
*
|
*
|
||||||
* @return " at {index} [character {character} line {line}]"
|
* @return " at {index} [character {character} line {line}]"
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return " at " + this.index + " [character " + this.character + " line " +
|
return " at " + this.index + " [character " + this.character + " line " +
|
||||||
this.line + "]";
|
this.line + "]";
|
||||||
|
|||||||
2
JSONWriter.java
Executable file → Normal file
2
JSONWriter.java
Executable file → Normal 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;
|
||||||
|
|||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Copyright (c) 2002 JSON.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
The Software shall be used for Good, not Evil.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
47
README
Executable file → Normal file
47
README
Executable file → Normal file
@@ -15,7 +15,7 @@ The license includes this restriction: "The software shall be used for good,
|
|||||||
not evil." If your conscience cannot live with that, then choose a different
|
not evil." If your conscience cannot live with that, then choose a different
|
||||||
package.
|
package.
|
||||||
|
|
||||||
The package compiles on Java 1.8.
|
The package compiles on Java 1.6-1.8.
|
||||||
|
|
||||||
|
|
||||||
JSONObject.java: The JSONObject can parse text from a String or a JSONTokener
|
JSONObject.java: The JSONObject can parse text from a String or a JSONTokener
|
||||||
@@ -32,6 +32,10 @@ tokens. It can be constructed from a String, Reader, or InputStream.
|
|||||||
JSONException.java: The JSONException is the standard exception type thrown
|
JSONException.java: The JSONException is the standard exception type thrown
|
||||||
by this package.
|
by this package.
|
||||||
|
|
||||||
|
JSONPointer.java: Implementation of
|
||||||
|
[JSON Pointer (RFC 6901)](https://tools.ietf.org/html/rfc6901). Supports
|
||||||
|
JSON Pointers both in the form of string representation and URI fragment
|
||||||
|
representation.
|
||||||
|
|
||||||
JSONString.java: The JSONString interface requires a toJSONString method,
|
JSONString.java: The JSONString interface requires a toJSONString method,
|
||||||
allowing an object to provide its own serialization.
|
allowing an object to provide its own serialization.
|
||||||
@@ -61,4 +65,43 @@ 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.
|
||||||
|
|
||||||
|
Although 1.6 compatibility is currently supported, it is not a project goal and may be
|
||||||
|
removed in some future release.
|
||||||
|
|
||||||
|
In compliance with RFC7159 page 10 section 9, the parser is more lax with what is valid
|
||||||
|
JSON than the Generator. For Example, the tab character (U+0009) is allowed when reading
|
||||||
|
JSON Text strings, but when output by the Generator, tab is properly converted to \t in
|
||||||
|
the string. Other instances may occur where reading invalid JSON text does not cause an
|
||||||
|
error to be generated. Malformed JSON Texts such as missing end " (quote) on strings or
|
||||||
|
invalid number formats (1.2e6.3) will cause errors as such documents can not be read
|
||||||
|
reliably.
|
||||||
|
|
||||||
|
Release history:
|
||||||
|
|
||||||
|
20160807 Java 1.6 compatability fixed, JSONArray.toList() and JSONObject.toMap(),
|
||||||
|
RFC4180 compatibility, JSONPointer, some exception fixes, optional XML type conversion.
|
||||||
|
Contains the latest code as of 7 Aug, 2016
|
||||||
|
|
||||||
|
20160212 Java 1.6 compatibility, OSGi bundle. Contains the latest code as of 12 Feb, 2016.
|
||||||
|
|
||||||
|
20151123 JSONObject and JSONArray initialization with generics. Contains the
|
||||||
|
latest code as of 23 Nov, 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:
|
||||||
|
https://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.json%22%20AND%20a%3A%22json%22
|
||||||
|
|||||||
232
XML.java
Executable file → Normal file
232
XML.java
Executable file → Normal file
@@ -1,7 +1,7 @@
|
|||||||
package org.json;
|
package org.json;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2002 JSON.org
|
Copyright (c) 2015 JSON.org
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -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 2014-05-03
|
* @version 2016-01-30
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("boxing")
|
||||||
public class XML {
|
public class XML {
|
||||||
|
|
||||||
/** The Character '&'. */
|
/** The Character '&'. */
|
||||||
@@ -63,13 +65,16 @@ public class XML {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace special characters with XML escapes:
|
* Replace special characters with XML escapes:
|
||||||
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* & <small>(ampersand)</small> is replaced by &amp;
|
* & <small>(ampersand)</small> is replaced by &amp;
|
||||||
* < <small>(less than)</small> is replaced by &lt;
|
* < <small>(less than)</small> is replaced by &lt;
|
||||||
* > <small>(greater than)</small> is replaced by &gt;
|
* > <small>(greater than)</small> is replaced by &gt;
|
||||||
* " <small>(double quote)</small> is replaced by &quot;
|
* " <small>(double quote)</small> is replaced by &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,10 +105,12 @@ 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.
|
*
|
||||||
* @throws JSONException
|
* @param string
|
||||||
|
* A string.
|
||||||
|
* @throws JSONException Thrown if the string contains whitespace or is empty.
|
||||||
*/
|
*/
|
||||||
public static void noSpace(String string) throws JSONException {
|
public static void noSpace(String string) throws JSONException {
|
||||||
int i, length = string.length();
|
int i, length = string.length();
|
||||||
@@ -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, boolean keepStrings)
|
||||||
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));
|
keepStrings ? 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));
|
keepStrings ? token : JSONObject.stringToValue(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nested element
|
|
||||||
|
|
||||||
} else if (token == LT) {
|
} else if (token == LT) {
|
||||||
if (parse(x, jsonobject, tagName)) {
|
// Nested element
|
||||||
|
if (parse(x, jsonobject, tagName,keepStrings)) {
|
||||||
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,108 +296,104 @@ public class XML {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method has been deprecated in favor of the
|
||||||
|
* {@link JSONObject.stringToValue(String)} method. Use it instead.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link JSONObject#stringToValue(String)} instead.
|
||||||
|
* @param string String to convert
|
||||||
|
* @return JSON value of this string or the string
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public static Object stringToValue(String string) {
|
||||||
|
return JSONObject.stringToValue(string);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to convert a string into a number, boolean, or null. If the string
|
* Convert a well-formed (but not necessarily valid) XML string into a
|
||||||
* can't be converted, return the string. This is much less ambitious than
|
* JSONObject. Some information may be lost in this transformation because
|
||||||
* JSONObject.stringToValue, especially because it does not attempt to
|
* JSON is a data format and XML is a document format. XML uses elements,
|
||||||
* convert plus forms, octal forms, hex forms, or E forms lacking decimal
|
* attributes, and content text, while JSON uses unordered collections of
|
||||||
* points.
|
* name/value pairs and arrays of values. JSON does not does not like to
|
||||||
* @param string A String.
|
* distinguish between elements and attributes. Sequences of similar
|
||||||
* @return A simple JSON value.
|
* elements are represented as JSONArrays. Content text may be placed in a
|
||||||
|
* "content" member. Comments, prologs, DTDs, and <code><[ [ ]]></code>
|
||||||
|
* are ignored.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* The source string.
|
||||||
|
* @return A JSONObject containing the structured data from the XML string.
|
||||||
|
* @throws JSONException Thrown if there is an errors while parsing the string
|
||||||
*/
|
*/
|
||||||
public static Object stringToValue(String string) {
|
public static JSONObject toJSONObject(String string) throws JSONException {
|
||||||
if ("true".equalsIgnoreCase(string)) {
|
return toJSONObject(string, false);
|
||||||
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><[ [ ]]></code>
|
||||||
* <code><[ [ ]]></code> are ignored.
|
* are ignored.
|
||||||
* @param string The source string.
|
*
|
||||||
|
* All values are converted as strings, for 1, 01, 29.0 will not be coerced to
|
||||||
|
* numbers but will instead be the exact value as seen in the XML document.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* The source string.
|
||||||
|
* @param keepStrings If true, then values will not be coerced into boolean
|
||||||
|
* or numeric values and will instead be left as strings
|
||||||
* @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 Thrown if there is an errors while parsing the string
|
||||||
*/
|
*/
|
||||||
public static JSONObject toJSONObject(String string) throws JSONException {
|
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
|
||||||
JSONObject jo = new JSONObject();
|
JSONObject jo = new JSONObject();
|
||||||
XMLTokener x = new XMLTokener(string);
|
XMLTokener x = new XMLTokener(string);
|
||||||
while (x.more() && x.skipPast("<")) {
|
while (x.more() && x.skipPast("<")) {
|
||||||
parse(x, jo, null);
|
parse(x, jo, null, keepStrings);
|
||||||
}
|
}
|
||||||
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 Thrown if there is an error parsing the string
|
||||||
*/
|
*/
|
||||||
public static String toString(Object object) throws JSONException {
|
public static String toString(Object object) throws JSONException {
|
||||||
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 Thrown if there is an error parsing the string
|
||||||
*/
|
*/
|
||||||
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 +401,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 +408,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 +433,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,33 +460,35 @@ 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.
|
|
||||||
|
|
||||||
} else {
|
if (object != null) {
|
||||||
if (object.getClass().isArray()) {
|
if (object.getClass().isArray()) {
|
||||||
object = new JSONArray(object);
|
object = new JSONArray(object);
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
||||||
} else {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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
2
XMLTokener.java
Executable file → Normal 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 {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user