diff --git a/src/main/java/org/json/JSONPointer.java b/src/main/java/org/json/JSONPointer.java index 27bd17440..df91a48b2 100644 --- a/src/main/java/org/json/JSONPointer.java +++ b/src/main/java/org/json/JSONPointer.java @@ -109,13 +109,9 @@ public static Builder builder() { // Segments for the JSONPointer string private final List refTokens; // Jane: add some fields and functions to access the next refTokens - private int currentInd; - - public String nextKey(){ - if (currentInd + 1 <= this.refTokens.size()){ - return refTokens.get(currentInd++); - } - return ""; + public List getRefTokens(){ + // read only + return new ArrayList<>(this.refTokens); } /** diff --git a/src/main/java/org/json/XML.java b/src/main/java/org/json/XML.java index af17b66f1..d93878f89 100644 --- a/src/main/java/org/json/XML.java +++ b/src/main/java/org/json/XML.java @@ -8,7 +8,9 @@ import java.io.StringReader; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; /** @@ -423,7 +425,7 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP context.accumulate(tagName, jsonObject); } } - + return false; } } @@ -435,6 +437,238 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP } } + // Jane + + public static boolean parseWithPath(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, List currPath, List targetPath, JSONObject to) + throws JSONException { + char c; + int i; + JSONObject jsonObject = null; + String string; + String tagName; + Object token; + XMLXsiTypeConverter xmlXsiTypeConverter; + + // Test for and skip past these forms: + // + // + // + // + // Report errors for these forms: + // <> + // <= + // << + + token = x.nextToken(); + + // "); + return false; + } + x.back(); + } else if (c == '[') { + token = x.nextToken(); + if ("CDATA".equals(token)) { + if (x.next() == '[') { + string = x.nextCDATA(); + if (string.length() > 0) { + currPath.add(config.getcDataTagName()); + context.accumulate(config.getcDataTagName(), string); + currPath.remove(currPath.size()-1); + } + return false; + } + } + throw x.syntaxError("Expected 'CDATA['"); + } + i = 1; + do { + token = x.nextMeta(); + if (token == null) { + throw x.syntaxError("Missing '>' after ' 0); + return false; + } else if (token == QUEST) { + + // "); + return false; + } else if (token == SLASH) { + + // Close tag + if (x.nextToken() != GT) { + throw x.syntaxError("Misshaped tag"); + } + if (config.getForceList().contains(tagName)) { + // Force the value to be an array + if (nilAttributeFound) { + context.append(tagName, JSONObject.NULL); + } else if (jsonObject.length() > 0) { + context.append(tagName, jsonObject); + } else { + context.put(tagName, new JSONArray()); + } + } else { + currPath.add(tagName); + if (nilAttributeFound) { + context.accumulate(tagName, JSONObject.NULL); + } else if (jsonObject.length() > 0) { + context.accumulate(tagName, jsonObject); + } else { + context.accumulate(tagName, ""); + } + currPath.remove(currPath.size()-1); + } + return false; + + } else if (token == GT) { + // Content, between <...> and + for (;;) { + token = x.nextContent(); + if (token == null) { + if (tagName != null) { + throw x.syntaxError("Unclosed tag " + tagName); + } + return false; + } else if (token instanceof String) { + string = (String) token; + if (string.length() > 0) { + currPath.add(config.getcDataTagName()); + if(xmlXsiTypeConverter != null) { + jsonObject.accumulate(config.getcDataTagName(), + stringToValue(string, xmlXsiTypeConverter)); + } else { + jsonObject.accumulate(config.getcDataTagName(), + config.isKeepStrings() ? string : stringToValue(string)); + } + currPath.remove(currPath.size()-1); + } + + } else if (token == LT) { + // Nested element + currPath.add(tagName); + if (parseWithPath(x, jsonObject, tagName, config, currPath, targetPath, to)) { + if (config.getForceList().contains(tagName)) { + // Force the value to be an array + + if (jsonObject.length() == 0) { + context.put(tagName, new JSONArray()); + } else if (jsonObject.length() == 1 + && jsonObject.opt(config.getcDataTagName()) != null) { + context.append(tagName, jsonObject.opt(config.getcDataTagName())); + } else { + context.append(tagName, jsonObject); + } + System.out.println(currPath.toString() + jsonObject.toString()); +// currPath.remove(currPath.size()-1); + } else { +// currPath.add(tagName); + if (jsonObject.length() == 0) { + context.accumulate(tagName, ""); + } else if (jsonObject.length() == 1 + && jsonObject.opt(config.getcDataTagName()) != null) { + context.accumulate(tagName, jsonObject.opt(config.getcDataTagName())); + } else { + context.accumulate(tagName, jsonObject); + } + System.out.println(currPath.toString() + jsonObject.toString()); +// currPath.remove(currPath.size()-1); + } + currPath.remove(currPath.size()-1); + return false; + }else{ + currPath.remove(currPath.size()-1); + } + + } + } + } else { + throw x.syntaxError("Misshaped tag"); + } + } + } + } + + /** * This method tries to convert the given string value to the target object * @param string String to convert @@ -567,7 +801,23 @@ public static JSONObject toJSONObject(Reader reader, JSONPointer path){ //TODO: For Jane public static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement){ - return new JSONObject(); + JSONObject jo = new JSONObject(); + XMLTokener x = new XMLTokener(reader); + while (x.more()) { + x.skipPast("<"); + if(x.more()) { + parseWithPath(x, jo, null, XMLParserConfiguration.ORIGINAL, new ArrayList(), path.getRefTokens(), replacement); + } + } + return jo; + } + + private static boolean isTwoPathSame(List aPath, List anotherPath){ + if (aPath.size()!=anotherPath.size()) return false; + for (int i = 0; i < aPath.size(); i++){ + if (!aPath.get(i).equals(anotherPath.get(i))) return false; + } + return true; } /** * Convert a well-formed (but not necessarily valid) XML string into a diff --git a/src/test/java/org/json/junit/JSONPointerTest.java b/src/test/java/org/json/junit/JSONPointerTest.java index 1b030d5f0..db7ea535b 100644 --- a/src/test/java/org/json/junit/JSONPointerTest.java +++ b/src/test/java/org/json/junit/JSONPointerTest.java @@ -40,15 +40,15 @@ private Object query(String pointer) { } // Jane: nextKey() unit tests - @Test - public void nextKeyTest(){ - JSONPointer pointer = new JSONPointer("/obj/other~0key/another~1key/0"); - assertEquals("obj", pointer.nextKey()); - assertEquals("other~key", pointer.nextKey()); - assertEquals("another/key", pointer.nextKey()); - assertEquals("0", pointer.nextKey()); - assertEquals("", pointer.nextKey()); - } +// @Test +// public void nextKeyTest(){ +// JSONPointer pointer = new JSONPointer("/obj/other~0key/another~1key/0"); +// assertEquals("obj", pointer.nextKey()); +// assertEquals("other~key", pointer.nextKey()); +// assertEquals("another/key", pointer.nextKey()); +// assertEquals("0", pointer.nextKey()); +// assertEquals("", pointer.nextKey()); +// } @Test public void emptyPointer() { assertTrue(new JSONObject(EXPECTED_COMPLETE_DOCUMENT).similar(query(""))); diff --git a/src/test/java/org/json/junit/XMLTest.java b/src/test/java/org/json/junit/XMLTest.java index 937658e86..ce7fbdcc2 100644 --- a/src/test/java/org/json/junit/XMLTest.java +++ b/src/test/java/org/json/junit/XMLTest.java @@ -279,6 +279,45 @@ public void shouldHandleSimpleXML() { compareFileToJSONObject(xmlStr, expectedStr); } + // Jane test parseWithPath + @Test + public void testParseWithPath(){ + String xmlStr = + "\n"+ + "\n"+ + "
\n"+ + " Joe Tester\n"+ + " [CDATA[Baker street 5]\n"+ + " \n"+ + " true\n"+ + " false\n"+ + " null\n"+ + " 42\n"+ + " -23\n"+ + " -23.45\n"+ + " -23x.45\n"+ + " 1, 2, 3, 4.1, 5.2\n"+ + "
\n"+ + "
"; + + String expectedStr = + "{\"addresses\":{\"address\":{\"street\":\"[CDATA[Baker street 5]\","+ + "\"name\":\"Joe Tester\",\"NothingHere\":\"\",TrueValue:true,\n"+ + "\"FalseValue\":false,\"NullValue\":null,\"PositiveValue\":42,\n"+ + "\"NegativeValue\":-23,\"DoubleValue\":-23.45,\"Nan\":-23x.45,\n"+ + "\"ArrayOfNum\":\"1, 2, 3, 4.1, 5.2\"\n"+ + "},\"xsi:noNamespaceSchemaLocation\":"+ + "\"test.xsd\",\"xmlns:xsi\":\"http://www.w3.org/2001/"+ + "XMLSchema-instance\"}}"; + + JSONObject expectedJsonObject = new JSONObject(expectedStr); + Reader reader = new StringReader(xmlStr); + JSONPointer pointer = new JSONPointer("/addresses/address/TrueValue"); + JSONObject jsonObject = XML.toJSONObject(reader, pointer, new JSONObject()); + } + + /** * Tests to verify that supported escapes in XML are converted to actual values. */