mirror of
https://github.com/stleary/JSON-java.git
synced 2025-08-02 19:15:27 -04:00
Added type conversion support
This commit is contained in:
parent
5541a6d91d
commit
250f74ef4d
@ -26,10 +26,12 @@ SOFTWARE.
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
/**
|
||||
* This provides static methods to convert an XML text into a JSONObject, and to
|
||||
* covert a JSONObject into an XML text.
|
||||
@ -72,6 +74,8 @@ public class XML {
|
||||
*/
|
||||
public static final String NULL_ATTR = "xsi:nil";
|
||||
|
||||
public static final String TYPE_ATTR = "xsi:type";
|
||||
|
||||
/**
|
||||
* Creates an iterator for navigating Code Points in a string instead of
|
||||
* characters. Once Java7 support is dropped, this can be replaced with
|
||||
@ -257,6 +261,7 @@ public class XML {
|
||||
String string;
|
||||
String tagName;
|
||||
Object token;
|
||||
String typeCastClass;
|
||||
|
||||
// Test for and skip past these forms:
|
||||
// <!-- ... -->
|
||||
@ -336,6 +341,7 @@ public class XML {
|
||||
token = null;
|
||||
jsonObject = new JSONObject();
|
||||
boolean nilAttributeFound = false;
|
||||
typeCastClass = null;
|
||||
for (;;) {
|
||||
if (token == null) {
|
||||
token = x.nextToken();
|
||||
@ -354,6 +360,9 @@ public class XML {
|
||||
&& NULL_ATTR.equals(string)
|
||||
&& Boolean.parseBoolean((String) token)) {
|
||||
nilAttributeFound = true;
|
||||
} else if(config.useValueTypeCast
|
||||
&& TYPE_ATTR.equals(string)) {
|
||||
typeCastClass = (String) token;
|
||||
} else if (!nilAttributeFound) {
|
||||
jsonObject.accumulate(string,
|
||||
config.isKeepStrings()
|
||||
@ -392,8 +401,13 @@ public class XML {
|
||||
} else if (token instanceof String) {
|
||||
string = (String) token;
|
||||
if (string.length() > 0) {
|
||||
jsonObject.accumulate(config.getcDataTagName(),
|
||||
config.isKeepStrings() ? string : stringToValue(string));
|
||||
if(typeCastClass != null) {
|
||||
jsonObject.accumulate(config.getcDataTagName(),
|
||||
stringToValue(string, typeCastClass));
|
||||
} else {
|
||||
jsonObject.accumulate(config.getcDataTagName(),
|
||||
config.isKeepStrings() ? string : stringToValue(string));
|
||||
}
|
||||
}
|
||||
|
||||
} else if (token == LT) {
|
||||
@ -418,6 +432,24 @@ public class XML {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method tries to convert the given string value to the target object
|
||||
* @param string String to convert
|
||||
* @param className target class name
|
||||
* @return JSON value of this string or the string
|
||||
*/
|
||||
public static Object stringToValue(String string, String className) {
|
||||
try {
|
||||
if(className.equals(String.class.getName())) return string;
|
||||
Class<?> clazz = Class.forName(className);
|
||||
Method method = clazz.getMethod("valueOf", String.class);
|
||||
return method.invoke(null, string);
|
||||
} catch (Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return stringToValue(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is the same as {@link JSONObject#stringToValue(String)}.
|
||||
*
|
||||
|
@ -56,6 +56,12 @@ public class XMLParserConfiguration {
|
||||
*/
|
||||
private boolean convertNilAttributeToNull;
|
||||
|
||||
/**
|
||||
* When parsing the XML into JSON, specifies if values with attribute xsi:type="java.lang.Integer"
|
||||
* should be kept as attribute(false), or they should be converted to the given type
|
||||
*/
|
||||
public boolean useValueTypeCast;
|
||||
|
||||
/**
|
||||
* Default parser configuration. Does not keep strings (tries to implicitly convert
|
||||
* values), and the CDATA Tag Name is "content".
|
||||
@ -106,9 +112,7 @@ public class XMLParserConfiguration {
|
||||
*/
|
||||
@Deprecated
|
||||
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName) {
|
||||
this.keepStrings = keepStrings;
|
||||
this.cDataTagName = cDataTagName;
|
||||
this.convertNilAttributeToNull = false;
|
||||
this(keepStrings, cDataTagName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,9 +129,27 @@ public class XMLParserConfiguration {
|
||||
*/
|
||||
@Deprecated
|
||||
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName, final boolean convertNilAttributeToNull) {
|
||||
this(keepStrings, cDataTagName, convertNilAttributeToNull, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the parser to use custom settings.
|
||||
* @param keepStrings <code>true</code> to parse all values as string.
|
||||
* <code>false</code> to try and convert XML string values into a JSON value.
|
||||
* @param cDataTagName <code>null</code> to disable CDATA processing. Any other value
|
||||
* to use that value as the JSONObject key name to process as CDATA.
|
||||
* @param convertNilAttributeToNull <code>true</code> to parse values with attribute xsi:nil="true" as null.
|
||||
* <code>false</code> to parse values with attribute xsi:nil="true" as {"xsi:nil":true}.
|
||||
* @param useValueTypeCast <code>true</code> to parse values with attribute xsi:type="java.lang.Integer" as
|
||||
* integer, xsi:type="java.lang.String" as string
|
||||
* <code>false</code> to parse values with attribute xsi:type="java.lang.Integer" as {"xsi:type":"java.lang.Integer"}.
|
||||
*/
|
||||
public XMLParserConfiguration (final boolean keepStrings, final String cDataTagName,
|
||||
final boolean convertNilAttributeToNull, final boolean useValueTypeCast ) {
|
||||
this.keepStrings = keepStrings;
|
||||
this.cDataTagName = cDataTagName;
|
||||
this.convertNilAttributeToNull = convertNilAttributeToNull;
|
||||
this.useValueTypeCast = useValueTypeCast;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -972,5 +972,32 @@ public class XMLTest {
|
||||
|
||||
assertEquals("Case insensitive Entity unescape", expectedStr, actualStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* test passes when xsi:type="java.lang.String" not converting to string
|
||||
*/
|
||||
@Test
|
||||
public void testToJsonWithTypeWhenTypeConversionDisabled() {
|
||||
final String originalXml = "<root><id xsi:type=\"java.lang.String\">1234</id></root>";
|
||||
final String expectedJsonString = "{\"root\":{\"id\":{\"xsi:type\":\"java.lang.String\",\"content\":1234}}}";
|
||||
final JSONObject expectedJson = new JSONObject(expectedJsonString);
|
||||
final JSONObject actualJson = XML.toJSONObject(originalXml, new XMLParserConfiguration());
|
||||
|
||||
Util.compareActualVsExpectedJsonObjects(actualJson,expectedJson);
|
||||
}
|
||||
|
||||
/**
|
||||
* test passes when xsi:type="java.lang.String" converting to String
|
||||
*/
|
||||
@Test
|
||||
public void testToJsonWithTypeWhenTypeConversionEnabled() {
|
||||
final String originalXml = "<root><id1 xsi:type=\"java.lang.String\">1234</id1>"
|
||||
+ "<id2 xsi:type=\"java.lang.Integer\">1234</id2></root>";
|
||||
final String expectedJsonString = "{\"root\":{\"id2\":1234,\"id1\":\"1234\"}}";
|
||||
final JSONObject expectedJson = new JSONObject(expectedJsonString);
|
||||
final JSONObject actualJson = XML.toJSONObject(originalXml, new XMLParserConfiguration(false,
|
||||
"content", false, true));
|
||||
Util.compareActualVsExpectedJsonObjects(actualJson,expectedJson);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user