#790 - Update XML with changes for string to number conversion.

For now the code remains duplicated in JSON and XML parsers.
Unit test cases updated to comply with number expectations.
This commit is contained in:
rudrajyoti biswas 2023-10-19 14:07:53 +05:30
parent 1d0775cce7
commit 2374766018
4 changed files with 54 additions and 12 deletions

View File

@ -486,8 +486,7 @@ public class XML {
* produced, then the value will just be a string. * produced, then the value will just be a string.
*/ */
char initial = string.charAt(0); if (potentialNumber(string)) {
if ((initial >= '0' && initial <= '9') || initial == '-') {
try { try {
return stringToNumber(string); return stringToNumber(string);
} catch (Exception ignore) { } catch (Exception ignore) {
@ -496,10 +495,38 @@ public class XML {
return string; return string;
} }
private static boolean potentialNumber(String value){
if (value == null || value.isEmpty()){
return false;
}
return potentialPositiveNumberStartingAtIndex(value, (value.charAt(0)=='-'?1:0));
}
private static boolean potentialPositiveNumberStartingAtIndex(String value,int index){
if (index >= value.length()){
return false;
}
return digitAtIndex(value, (value.charAt(index)=='.'?index+1:index));
}
private static boolean digitAtIndex(String value, int index){
if (index >= value.length()){
return false;
}
return value.charAt(index) >= '0' && value.charAt(index) <= '9';
}
/** /**
* direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support. * direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support.
*/ */
private static Number stringToNumber(final String val) throws NumberFormatException { private static Number stringToNumber(final String input) throws NumberFormatException {
String val = input;
if (val.startsWith(".")){
val = "0"+val;
}
if (val.startsWith("-.")){
val = "-0."+val.substring(2);
}
char initial = val.charAt(0); char initial = val.charAt(0);
if ((initial >= '0' && initial <= '9') || initial == '-') { if ((initial >= '0' && initial <= '9') || initial == '-') {
// decimal representation // decimal representation
@ -518,25 +545,25 @@ public class XML {
try { try {
Double d = Double.valueOf(val); Double d = Double.valueOf(val);
if(d.isNaN() || d.isInfinite()) { if(d.isNaN() || d.isInfinite()) {
throw new NumberFormatException("val ["+val+"] is not a valid number."); throw new NumberFormatException("val ["+input+"] is not a valid number.");
} }
return d; return d;
} catch (NumberFormatException ignore) { } catch (NumberFormatException ignore) {
throw new NumberFormatException("val ["+val+"] is not a valid number."); throw new NumberFormatException("val ["+input+"] is not a valid number.");
} }
} }
} }
// block items like 00 01 etc. Java number parsers treat these as Octal. val = removeLeadingZerosOfNumber(input);
if(initial == '0' && val.length() > 1) { if(initial == '0' && val.length() > 1) {
char at1 = val.charAt(1); char at1 = val.charAt(1);
if(at1 >= '0' && at1 <= '9') { if(at1 >= '0' && at1 <= '9') {
throw new NumberFormatException("val ["+val+"] is not a valid number."); throw new NumberFormatException("val ["+input+"] is not a valid number.");
} }
} else if (initial == '-' && val.length() > 2) { } else if (initial == '-' && val.length() > 2) {
char at1 = val.charAt(1); char at1 = val.charAt(1);
char at2 = val.charAt(2); char at2 = val.charAt(2);
if(at1 == '0' && at2 >= '0' && at2 <= '9') { if(at1 == '0' && at2 >= '0' && at2 <= '9') {
throw new NumberFormatException("val ["+val+"] is not a valid number."); throw new NumberFormatException("val ["+input+"] is not a valid number.");
} }
} }
// integer representation. // integer representation.
@ -556,7 +583,7 @@ public class XML {
} }
return bi; return bi;
} }
throw new NumberFormatException("val ["+val+"] is not a valid number."); throw new NumberFormatException("val ["+input+"] is not a valid number.");
} }
/** /**
@ -973,4 +1000,19 @@ public class XML {
} }
return sb.toString(); return sb.toString();
} }
private static String removeLeadingZerosOfNumber(String value){
if (value.equals("-")){return value;}
boolean negativeFirstChar = (value.charAt(0) == '-');
int counter = negativeFirstChar ? 1:0;
while (counter < value.length()){
if (value.charAt(counter) != '0'){
if (negativeFirstChar) {return "-".concat(value.substring(counter));}
return value.substring(counter);
}
++counter;
}
if (negativeFirstChar) {return "-0";}
return "0";
}
} }

View File

@ -709,7 +709,7 @@ public class JSONMLTest {
@Test @Test
public void testToJSONArray_jsonOutput() { public void testToJSONArray_jsonOutput() {
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>"; final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",1],[\"id\",\"00\"],[\"id\",0],[\"item\",{\"id\":\"01\"}],[\"title\",true]]"; final String expectedJsonString = "[\"root\",[\"id\",1],[\"id\",1],[\"id\",0],[\"id\",0],[\"item\",{\"id\":1}],[\"title\",true]]";
final JSONArray actualJsonOutput = JSONML.toJSONArray(originalXml, false); final JSONArray actualJsonOutput = JSONML.toJSONArray(originalXml, false);
assertEquals(expectedJsonString, actualJsonOutput.toString()); assertEquals(expectedJsonString, actualJsonOutput.toString());
} }

View File

@ -733,7 +733,7 @@ public class XMLConfigurationTest {
@Test @Test
public void testToJSONArray_jsonOutput() { public void testToJSONArray_jsonOutput() {
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>"; final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
final JSONObject expected = new JSONObject("{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}"); final JSONObject expected = new JSONObject("{\"root\":{\"item\":{\"id\":1},\"id\":[1,1,0,0],\"title\":true}}");
final JSONObject actualJsonOutput = XML.toJSONObject(originalXml, final JSONObject actualJsonOutput = XML.toJSONObject(originalXml,
new XMLParserConfiguration().withKeepStrings(false)); new XMLParserConfiguration().withKeepStrings(false));
Util.compareActualVsExpectedJsonObjects(actualJsonOutput,expected); Util.compareActualVsExpectedJsonObjects(actualJsonOutput,expected);

View File

@ -791,7 +791,7 @@ public class XMLTest {
@Test @Test
public void testToJSONArray_jsonOutput() { public void testToJSONArray_jsonOutput() {
final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>"; final String originalXml = "<root><id>01</id><id>1</id><id>00</id><id>0</id><item id=\"01\"/><title>True</title></root>";
final JSONObject expectedJson = new JSONObject("{\"root\":{\"item\":{\"id\":\"01\"},\"id\":[\"01\",1,\"00\",0],\"title\":true}}"); final JSONObject expectedJson = new JSONObject("{\"root\":{\"item\":{\"id\":1},\"id\":[1,1,0,0],\"title\":true}}");
final JSONObject actualJsonOutput = XML.toJSONObject(originalXml, false); final JSONObject actualJsonOutput = XML.toJSONObject(originalXml, false);
Util.compareActualVsExpectedJsonObjects(actualJsonOutput,expectedJson); Util.compareActualVsExpectedJsonObjects(actualJsonOutput,expectedJson);