diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java
index e14bb34e9..7e4b0bb0c 100644
--- a/src/main/java/org/json/XML.java
+++ b/src/main/java/org/json/XML.java
@@ -391,8 +391,13 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
context.append(tagName, JSONObject.NULL);
} else if (jsonObject.length() > 0) {
context.append(tagName, jsonObject);
- } else {
+ } else if(context.isEmpty()) { //avoids resetting the array in case of an empty tag in the middle or end
context.put(tagName, new JSONArray());
+ if (jsonObject.isEmpty()){
+ context.append(tagName, "");
+ }
+ } else {
+ context.append(tagName, "");
}
} else {
if (nilAttributeFound) {
@@ -451,7 +456,11 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
if (config.getForceList().contains(tagName)) {
// Force the value to be an array
if (jsonObject.length() == 0) {
- context.put(tagName, new JSONArray());
+ //avoids resetting the array in case of an empty element in the middle or end
+ if(context.isEmpty()) {
+ context.put(tagName, new JSONArray());
+ }
+ context.append(tagName, "");
} else if (jsonObject.length() == 1
&& jsonObject.opt(config.getcDataTagName()) != null) {
context.append(tagName, jsonObject.opt(config.getcDataTagName()));
diff --git a/src/test/java/org/json/junit/XMLConfigurationTest.java b/src/test/java/org/json/junit/XMLConfigurationTest.java
index ca1980c8a..e8ff3b60c 100755
--- a/src/test/java/org/json/junit/XMLConfigurationTest.java
+++ b/src/test/java/org/json/junit/XMLConfigurationTest.java
@@ -1092,7 +1092,7 @@ public void testEmptyForceList() {
"";
String expectedStr =
- "{\"addresses\":[]}";
+ "{\"addresses\":[\"\"]}";
Set forceList = new HashSet();
forceList.add("addresses");
@@ -1130,7 +1130,7 @@ public void testEmptyTagForceList() {
"";
String expectedStr =
- "{\"addresses\":[]}";
+ "{\"addresses\":[\"\"]}";
Set forceList = new HashSet();
forceList.add("addresses");
@@ -1144,6 +1144,157 @@ public void testEmptyTagForceList() {
Util.compareActualVsExpectedJsonObjects(jsonObject, expetedJsonObject);
}
+ @Test
+ public void testForceListWithLastElementAsEmptyTag(){
+ final String originalXml = "1";
+ final String expectedJsonString = "{\"root\":{\"id\":[1,\"\"]}}";
+
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ final JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withKeepStrings(false)
+ .withcDataTagName("content")
+ .withForceList(forceListCandidates)
+ .withConvertNilAttributeToNull(true));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListWithFirstElementAsEmptyTag(){
+ final String originalXml = "1";
+ final String expectedJsonString = "{\"root\":{\"id\":[\"\",1]}}";
+
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ final JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withKeepStrings(false)
+ .withcDataTagName("content")
+ .withForceList(forceListCandidates)
+ .withConvertNilAttributeToNull(true));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListWithMiddleElementAsEmptyTag(){
+ final String originalXml = "12";
+ final String expectedJsonString = "{\"root\":{\"id\":[1,\"\",2]}}";
+
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ final JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withKeepStrings(false)
+ .withcDataTagName("content")
+ .withForceList(forceListCandidates)
+ .withConvertNilAttributeToNull(true));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListWithLastElementAsEmpty(){
+ final String originalXml = "1";
+ final String expectedJsonString = "{\"root\":{\"id\":[1,\"\"]}}";
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ final JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withKeepStrings(false)
+ .withForceList(forceListCandidates)
+ .withConvertNilAttributeToNull(true));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListWithFirstElementAsEmpty(){
+ final String originalXml = "1";
+ final String expectedJsonString = "{\"root\":{\"id\":[\"\",1]}}";
+
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ final JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withKeepStrings(false)
+ .withForceList(forceListCandidates)
+ .withConvertNilAttributeToNull(true));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListWithMiddleElementAsEmpty(){
+ final String originalXml = "12";
+ final String expectedJsonString = "{\"root\":{\"id\":[1,\"\",2]}}";
+
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ final JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withKeepStrings(false)
+ .withForceList(forceListCandidates)
+ .withConvertNilAttributeToNull(true));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListEmptyAndEmptyTagsMixed(){
+ final String originalXml = "12";
+ final String expectedJsonString = "{\"root\":{\"id\":[\"\",\"\",1,\"\",\"\",2]}}";
+
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ final JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withKeepStrings(false)
+ .withForceList(forceListCandidates)
+ .withConvertNilAttributeToNull(true));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListConsistencyWithDefault() {
+ final String originalXml = "01";
+ final String expectedJsonString = "{\"root\":{\"id\":[0,1,\"\",\"\"]}}";
+
+ // confirm expected result of default array-of-tags processing
+ JSONObject json = XML.toJSONObject(originalXml);
+ assertEquals(expectedJsonString, json.toString());
+
+ // confirm forceList array-of-tags processing is consistent with default processing
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withForceList(forceListCandidates));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListInitializesAnArrayWithAnEmptyElement(){
+ final String originalXml = "";
+ final String expectedJsonString = "{\"root\":{\"id\":[\"\"]}}";
+
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withForceList(forceListCandidates));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
+ @Test
+ public void testForceListInitializesAnArrayWithAnEmptyTag(){
+ final String originalXml = "";
+ final String expectedJsonString = "{\"root\":{\"id\":[\"\"]}}";
+
+ HashSet forceListCandidates = new HashSet<>();
+ forceListCandidates.add("id");
+ JSONObject json = XML.toJSONObject(originalXml,
+ new XMLParserConfiguration()
+ .withForceList(forceListCandidates));
+ assertEquals(expectedJsonString, json.toString());
+ }
+
@Test
public void testMaxNestingDepthIsSet() {
XMLParserConfiguration xmlParserConfiguration = XMLParserConfiguration.ORIGINAL;