mirror of
https://github.com/ethauvin/JSON-java.git
synced 2025-06-17 07:50:52 -07:00
Merge remote-tracking branch 'origin/master' into AndroidSupport
This commit is contained in:
commit
057e0c75ca
6 changed files with 187 additions and 82 deletions
|
@ -1230,7 +1230,7 @@ public class JSONArray implements Iterable<Object> {
|
||||||
* Queries and returns a value from this object using {@code jsonPointer}, or
|
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||||
* returns null if the query fails due to a missing key.
|
* returns null if the query fails due to a missing key.
|
||||||
*
|
*
|
||||||
* @param The JSON pointer
|
* @param jsonPointer The JSON pointer
|
||||||
* @return the queried value or {@code null}
|
* @return the queried value or {@code null}
|
||||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||||
*/
|
*/
|
||||||
|
@ -1323,8 +1323,9 @@ public class JSONArray implements Iterable<Object> {
|
||||||
* whitespace is added. If it is not possible to produce a syntactically
|
* whitespace is added. If it is not possible to produce a syntactically
|
||||||
* correct JSON text then null will be returned instead. This could occur if
|
* correct JSON text then null will be returned instead. This could occur if
|
||||||
* the array contains an invalid number.
|
* the array contains an invalid number.
|
||||||
* <p>
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @return a printable, displayable, transmittable representation of the
|
* @return a printable, displayable, transmittable representation of the
|
||||||
* array.
|
* array.
|
||||||
|
@ -1339,8 +1340,23 @@ public class JSONArray implements Iterable<Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a pretty-printed JSON text of this JSONArray. Warning: This method
|
* Make a pretty-printed JSON text of this JSONArray.
|
||||||
* assumes that the data structure is acyclical.
|
*
|
||||||
|
* <p>If <code>indentFactor > 0</code> and the {@link JSONArray} has only
|
||||||
|
* one element, then the array will be output on a single line:
|
||||||
|
* <pre>{@code [1]}</pre>
|
||||||
|
*
|
||||||
|
* <p>If an array has 2 or more elements, then it will be output across
|
||||||
|
* multiple lines: <pre>{@code
|
||||||
|
* [
|
||||||
|
* 1,
|
||||||
|
* "value 2",
|
||||||
|
* 3
|
||||||
|
* ]
|
||||||
|
* }</pre>
|
||||||
|
* <p><b>
|
||||||
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @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.
|
||||||
|
@ -1360,8 +1376,9 @@ public class JSONArray implements Iterable<Object> {
|
||||||
/**
|
/**
|
||||||
* Write the contents of the JSONArray as JSON text to a writer. For
|
* Write the contents of the JSONArray as JSON text to a writer. For
|
||||||
* compactness, no whitespace is added.
|
* compactness, no whitespace is added.
|
||||||
* <p>
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
*</b>
|
||||||
*
|
*
|
||||||
* @return The writer.
|
* @return The writer.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
|
@ -1371,10 +1388,23 @@ public class JSONArray implements Iterable<Object> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the contents of the JSONArray as JSON text to a writer. For
|
* Write the contents of the JSONArray as JSON text to a writer.
|
||||||
* compactness, no whitespace is added.
|
*
|
||||||
* <p>
|
* <p>If <code>indentFactor > 0</code> and the {@link JSONArray} has only
|
||||||
|
* one element, then the array will be output on a single line:
|
||||||
|
* <pre>{@code [1]}</pre>
|
||||||
|
*
|
||||||
|
* <p>If an array has 2 or more elements, then it will be output across
|
||||||
|
* multiple lines: <pre>{@code
|
||||||
|
* [
|
||||||
|
* 1,
|
||||||
|
* "value 2",
|
||||||
|
* 3
|
||||||
|
* ]
|
||||||
|
* }</pre>
|
||||||
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* Writes the serialized JSON
|
* Writes the serialized JSON
|
||||||
|
|
|
@ -172,7 +172,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, keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token));
|
newjo.accumulate(attribute, keepStrings ? ((String)token) :XML.stringToValue((String)token));
|
||||||
token = null;
|
token = null;
|
||||||
} else {
|
} else {
|
||||||
newjo.accumulate(attribute, "");
|
newjo.accumulate(attribute, "");
|
||||||
|
|
136
JSONObject.java
136
JSONObject.java
|
@ -1,5 +1,7 @@
|
||||||
package org.json;
|
package org.json;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2002 JSON.org
|
Copyright (c) 2002 JSON.org
|
||||||
|
|
||||||
|
@ -28,6 +30,7 @@ import java.io.IOException;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
@ -228,7 +231,21 @@ public class JSONObject {
|
||||||
if (c != ':') {
|
if (c != ':') {
|
||||||
throw x.syntaxError("Expected a ':' after a key");
|
throw x.syntaxError("Expected a ':' after a key");
|
||||||
}
|
}
|
||||||
this.putOnce(key, x.nextValue());
|
|
||||||
|
// Use syntaxError(..) to include error location
|
||||||
|
|
||||||
|
if (key != null) {
|
||||||
|
// Check if key exists
|
||||||
|
if (this.opt(key) != null) {
|
||||||
|
// key already exists
|
||||||
|
throw x.syntaxError("Duplicate key \"" + key + "\"");
|
||||||
|
}
|
||||||
|
// Only add value if non-null
|
||||||
|
Object value = x.nextValue();
|
||||||
|
if (value!=null) {
|
||||||
|
this.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Pairs are separated by ','.
|
// Pairs are separated by ','.
|
||||||
|
|
||||||
|
@ -276,15 +293,18 @@ public class JSONObject {
|
||||||
* <code>"is"</code> followed by an uppercase letter, the method is invoked,
|
* <code>"is"</code> followed by an uppercase letter, the method is invoked,
|
||||||
* and a key and the value returned from the getter method are put into the
|
* and a key and the value returned from the getter method are put into the
|
||||||
* new JSONObject.
|
* new JSONObject.
|
||||||
*
|
* <p>
|
||||||
* The key is formed by removing the <code>"get"</code> or <code>"is"</code>
|
* The key is formed by removing the <code>"get"</code> or <code>"is"</code>
|
||||||
* prefix. If the second remaining character is not upper case, then the
|
* prefix. If the second remaining character is not upper case, then the
|
||||||
* first character is converted to lower case.
|
* first character is converted to lower case.
|
||||||
*
|
* <p>
|
||||||
* For example, if an object has a method named <code>"getName"</code>, and
|
* For example, if an object has a method named <code>"getName"</code>, and
|
||||||
* if the result of calling <code>object.getName()</code> is
|
* if the result of calling <code>object.getName()</code> is
|
||||||
* <code>"Larry Fine"</code>, then the JSONObject will contain
|
* <code>"Larry Fine"</code>, then the JSONObject will contain
|
||||||
* <code>"name": "Larry Fine"</code>.
|
* <code>"name": "Larry Fine"</code>.
|
||||||
|
* <p>
|
||||||
|
* Methods that return <code>void</code> as well as <code>static</code>
|
||||||
|
* methods are ignored.
|
||||||
*
|
*
|
||||||
* @param bean
|
* @param bean
|
||||||
* An object that has getter methods that should be used to make
|
* An object that has getter methods that should be used to make
|
||||||
|
@ -1388,6 +1408,15 @@ public class JSONObject {
|
||||||
return NULL.equals(object) ? defaultValue : object.toString();
|
return NULL.equals(object) ? defaultValue : object.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the internal map of the JSONObject with the bean properties.
|
||||||
|
* The bean can not be recursive.
|
||||||
|
*
|
||||||
|
* @see JSONObject#JSONObject(Object)
|
||||||
|
*
|
||||||
|
* @param bean
|
||||||
|
* the bean
|
||||||
|
*/
|
||||||
private void populateMap(Object bean) {
|
private void populateMap(Object bean) {
|
||||||
Class<?> klass = bean.getClass();
|
Class<?> klass = bean.getClass();
|
||||||
|
|
||||||
|
@ -1397,39 +1426,52 @@ public class JSONObject {
|
||||||
|
|
||||||
Method[] methods = includeSuperClass ? klass.getMethods() : klass
|
Method[] methods = includeSuperClass ? klass.getMethods() : klass
|
||||||
.getDeclaredMethods();
|
.getDeclaredMethods();
|
||||||
for (int i = 0; i < methods.length; i += 1) {
|
for (final Method method : methods) {
|
||||||
try {
|
final int modifiers = method.getModifiers();
|
||||||
Method method = methods[i];
|
if (Modifier.isPublic(modifiers)
|
||||||
if (Modifier.isPublic(method.getModifiers())) {
|
&& !Modifier.isStatic(modifiers)
|
||||||
String name = method.getName();
|
&& method.getParameterTypes().length == 0
|
||||||
String key = "";
|
&& !method.isBridge()
|
||||||
if (name.startsWith("get")) {
|
&& method.getReturnType() != Void.TYPE ) {
|
||||||
if ("getClass".equals(name)
|
final String name = method.getName();
|
||||||
|| "getDeclaringClass".equals(name)) {
|
String key;
|
||||||
key = "";
|
if (name.startsWith("get")) {
|
||||||
} else {
|
if ("getClass".equals(name) || "getDeclaringClass".equals(name)) {
|
||||||
key = name.substring(3);
|
continue;
|
||||||
}
|
}
|
||||||
} else if (name.startsWith("is")) {
|
key = name.substring(3);
|
||||||
key = name.substring(2);
|
} else if (name.startsWith("is")) {
|
||||||
|
key = name.substring(2);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key.length() > 0
|
||||||
|
&& Character.isUpperCase(key.charAt(0))) {
|
||||||
|
if (key.length() == 1) {
|
||||||
|
key = key.toLowerCase(Locale.ROOT);
|
||||||
|
} else if (!Character.isUpperCase(key.charAt(1))) {
|
||||||
|
key = key.substring(0, 1).toLowerCase(Locale.ROOT)
|
||||||
|
+ key.substring(1);
|
||||||
}
|
}
|
||||||
if (key.length() > 0
|
|
||||||
&& Character.isUpperCase(key.charAt(0))
|
|
||||||
&& method.getParameterTypes().length == 0) {
|
|
||||||
if (key.length() == 1) {
|
|
||||||
key = key.toLowerCase(Locale.ROOT);
|
|
||||||
} else if (!Character.isUpperCase(key.charAt(1))) {
|
|
||||||
key = key.substring(0, 1).toLowerCase(Locale.ROOT)
|
|
||||||
+ key.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object result = method.invoke(bean, (Object[]) null);
|
try {
|
||||||
|
final Object result = method.invoke(bean);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
this.map.put(key, wrap(result));
|
this.map.put(key, wrap(result));
|
||||||
|
// we don't use the result anywhere outside of wrap
|
||||||
|
// if it's a resource we should be sure to close it after calling toString
|
||||||
|
if(result instanceof Closeable) {
|
||||||
|
try {
|
||||||
|
((Closeable)result).close();
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (IllegalAccessException ignore) {
|
||||||
|
} catch (IllegalArgumentException ignore) {
|
||||||
|
} catch (InvocationTargetException ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception ignore) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1676,7 +1718,7 @@ public class JSONObject {
|
||||||
* Queries and returns a value from this object using {@code jsonPointer}, or
|
* Queries and returns a value from this object using {@code jsonPointer}, or
|
||||||
* returns null if the query fails due to a missing key.
|
* returns null if the query fails due to a missing key.
|
||||||
*
|
*
|
||||||
* @param The JSON pointer
|
* @param jsonPointer The JSON pointer
|
||||||
* @return the queried value or {@code null}
|
* @return the queried value or {@code null}
|
||||||
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
* @throws IllegalArgumentException if {@code jsonPointer} has invalid syntax
|
||||||
*/
|
*/
|
||||||
|
@ -2004,8 +2046,9 @@ public class JSONObject {
|
||||||
* Make a JSON text of this JSONObject. For compactness, no whitespace is
|
* Make a JSON text of this JSONObject. For compactness, no whitespace is
|
||||||
* added. If this would not result in a syntactically correct JSON text,
|
* added. If this would not result in a syntactically correct JSON text,
|
||||||
* then null will be returned instead.
|
* then null will be returned instead.
|
||||||
* <p>
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @return a printable, displayable, portable, transmittable representation
|
* @return a printable, displayable, portable, transmittable representation
|
||||||
* of the object, beginning with <code>{</code> <small>(left
|
* of the object, beginning with <code>{</code> <small>(left
|
||||||
|
@ -2023,8 +2066,20 @@ public class JSONObject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a pretty-printed JSON text of this JSONObject.
|
* Make a pretty-printed JSON text of this JSONObject.
|
||||||
* <p>
|
*
|
||||||
|
* <p>If <code>indentFactor > 0</code> and the {@link JSONObject}
|
||||||
|
* has only one key, then the object will be output on a single line:
|
||||||
|
* <pre>{@code {"key": 1}}</pre>
|
||||||
|
*
|
||||||
|
* <p>If an object has 2 or more keys, then it will be output across
|
||||||
|
* multiple lines: <code><pre>{
|
||||||
|
* "key1": 1,
|
||||||
|
* "key2": "value 2",
|
||||||
|
* "key3": 3
|
||||||
|
* }</pre></code>
|
||||||
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @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.
|
||||||
|
@ -2130,8 +2185,9 @@ public class JSONObject {
|
||||||
/**
|
/**
|
||||||
* Write the contents of the JSONObject as JSON text to a writer. For
|
* Write the contents of the JSONObject as JSON text to a writer. For
|
||||||
* compactness, no whitespace is added.
|
* compactness, no whitespace is added.
|
||||||
* <p>
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @return The writer.
|
* @return The writer.
|
||||||
* @throws JSONException
|
* @throws JSONException
|
||||||
|
@ -2196,8 +2252,20 @@ public class JSONObject {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the contents of the JSONObject as JSON text to a writer.
|
* Write the contents of the JSONObject as JSON text to a writer.
|
||||||
* <p>
|
*
|
||||||
|
* <p>If <code>indentFactor > 0</code> and the {@link JSONObject}
|
||||||
|
* has only one key, then the object will be output on a single line:
|
||||||
|
* <pre>{@code {"key": 1}}</pre>
|
||||||
|
*
|
||||||
|
* <p>If an object has 2 or more keys, then it will be output across
|
||||||
|
* multiple lines: <code><pre>{
|
||||||
|
* "key1": 1,
|
||||||
|
* "key2": "value 2",
|
||||||
|
* "key3": 3
|
||||||
|
* }</pre></code>
|
||||||
|
* <p><b>
|
||||||
* Warning: This method assumes that the data structure is acyclical.
|
* Warning: This method assumes that the data structure is acyclical.
|
||||||
|
* </b>
|
||||||
*
|
*
|
||||||
* @param writer
|
* @param writer
|
||||||
* Writes the serialized JSON
|
* Writes the serialized JSON
|
||||||
|
|
2
README
2
README
|
@ -89,6 +89,8 @@ invalid number formats (1.2e6.3) will cause errors as such documents can not be
|
||||||
reliably.
|
reliably.
|
||||||
|
|
||||||
Release history:
|
Release history:
|
||||||
|
20171018 Checkpoint for recent commits.
|
||||||
|
|
||||||
20170516 Roll up recent commits.
|
20170516 Roll up recent commits.
|
||||||
|
|
||||||
20160810 Revert code that was breaking opt*() methods.
|
20160810 Revert code that was breaking opt*() methods.
|
||||||
|
|
42
XML.java
42
XML.java
|
@ -140,7 +140,7 @@ public class XML {
|
||||||
if (mustEscape(cp)) {
|
if (mustEscape(cp)) {
|
||||||
sb.append("&#x");
|
sb.append("&#x");
|
||||||
sb.append(Integer.toHexString(cp));
|
sb.append(Integer.toHexString(cp));
|
||||||
sb.append(";");
|
sb.append(';');
|
||||||
} else {
|
} else {
|
||||||
sb.appendCodePoint(cp);
|
sb.appendCodePoint(cp);
|
||||||
}
|
}
|
||||||
|
@ -190,31 +190,7 @@ public class XML {
|
||||||
final int semic = string.indexOf(';', i);
|
final int semic = string.indexOf(';', i);
|
||||||
if (semic > i) {
|
if (semic > i) {
|
||||||
final String entity = string.substring(i + 1, semic);
|
final String entity = string.substring(i + 1, semic);
|
||||||
if (entity.charAt(0) == '#') {
|
sb.append(XMLTokener.unescapeEntity(entity));
|
||||||
int cp;
|
|
||||||
if (entity.charAt(1) == 'x') {
|
|
||||||
// hex encoded unicode
|
|
||||||
cp = Integer.parseInt(entity.substring(2), 16);
|
|
||||||
} else {
|
|
||||||
// decimal encoded unicode
|
|
||||||
cp = Integer.parseInt(entity.substring(1));
|
|
||||||
}
|
|
||||||
sb.appendCodePoint(cp);
|
|
||||||
} else {
|
|
||||||
if ("quot".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('"');
|
|
||||||
} else if ("amp".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('&');
|
|
||||||
} else if ("apos".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('\'');
|
|
||||||
} else if ("lt".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('<');
|
|
||||||
} else if ("gt".equalsIgnoreCase(entity)) {
|
|
||||||
sb.append('>');
|
|
||||||
} else {// unsupported xml entity. leave encoded
|
|
||||||
sb.append('&').append(entity).append(';');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// skip past the entity we just parsed.
|
// skip past the entity we just parsed.
|
||||||
i += entity.length() + 1;
|
i += entity.length() + 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -363,7 +339,7 @@ public class XML {
|
||||||
throw x.syntaxError("Missing value");
|
throw x.syntaxError("Missing value");
|
||||||
}
|
}
|
||||||
jsonobject.accumulate(string,
|
jsonobject.accumulate(string,
|
||||||
keepStrings ? unescape((String)token) : stringToValue((String) token));
|
keepStrings ? ((String)token) : stringToValue((String) token));
|
||||||
token = null;
|
token = null;
|
||||||
} else {
|
} else {
|
||||||
jsonobject.accumulate(string, "");
|
jsonobject.accumulate(string, "");
|
||||||
|
@ -395,7 +371,7 @@ public class XML {
|
||||||
string = (String) token;
|
string = (String) token;
|
||||||
if (string.length() > 0) {
|
if (string.length() > 0) {
|
||||||
jsonobject.accumulate("content",
|
jsonobject.accumulate("content",
|
||||||
keepStrings ? unescape(string) : stringToValue(string));
|
keepStrings ? string : stringToValue(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (token == LT) {
|
} else if (token == LT) {
|
||||||
|
@ -422,14 +398,15 @@ public class XML {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is the same as {@link JSONObject.stringToValue(String)}
|
* This method is the same as {@link JSONObject#stringToValue(String)}.
|
||||||
* except that this also tries to unescape String values.
|
|
||||||
*
|
*
|
||||||
* @param string String to convert
|
* @param string String to convert
|
||||||
* @return JSON value of this string or the string
|
* @return JSON value of this string or the string
|
||||||
*/
|
*/
|
||||||
|
// To maintain compatibility with the Android API, this method is a direct copy of
|
||||||
|
// the one in JSONObject. Changes made here should be reflected there.
|
||||||
public static Object stringToValue(String string) {
|
public static Object stringToValue(String string) {
|
||||||
if (string.equals("")) {
|
if (string.equals("")) {
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
if (string.equalsIgnoreCase("true")) {
|
if (string.equalsIgnoreCase("true")) {
|
||||||
|
@ -470,8 +447,7 @@ public class XML {
|
||||||
} catch (Exception ignore) {
|
} catch (Exception ignore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return string;
|
||||||
return unescape(string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -138,8 +138,37 @@ public class XMLTokener extends JSONTokener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String string = sb.toString();
|
String string = sb.toString();
|
||||||
Object object = entity.get(string);
|
return unescapeEntity(string);
|
||||||
return object != null ? object : ampersand + string + ";";
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unescapes an XML entity encoding;
|
||||||
|
* @param e entity (only the actual entity value, not the preceding & or ending ;
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static String unescapeEntity(String e) {
|
||||||
|
// validate
|
||||||
|
if (e == null || e.isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// if our entity is an encoded unicode point, parse it.
|
||||||
|
if (e.charAt(0) == '#') {
|
||||||
|
int cp;
|
||||||
|
if (e.charAt(1) == 'x') {
|
||||||
|
// hex encoded unicode
|
||||||
|
cp = Integer.parseInt(e.substring(2), 16);
|
||||||
|
} else {
|
||||||
|
// decimal encoded unicode
|
||||||
|
cp = Integer.parseInt(e.substring(1));
|
||||||
|
}
|
||||||
|
return new String(new int[] {cp},0,1);
|
||||||
|
}
|
||||||
|
Character knownEntity = entity.get(e);
|
||||||
|
if(knownEntity==null) {
|
||||||
|
// we don't know the entity so keep it encoded
|
||||||
|
return '&' + e + ';';
|
||||||
|
}
|
||||||
|
return knownEntity.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue