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;