From 7a98f180700ac150798c2bb7ee155c01e8040f8e Mon Sep 17 00:00:00 2001
From: susunsheng org/json/XML.java: org/json/junit/XMLMyTest.java: Task2 and task5 using library inside run less time than using library outside. This document's intention is to explain to new-comers the basics of this project We don't need to have a JSON docuemnt to work. This project also admits conversions from other type of files. Secondly, we can also convert from JSON to those type of files. This document's intention is to explain to new-comers the basics of this project org/json/execption/JSONFoundExecption.java: org/json/junit/XMLMyTest.java: org/json/XML.java: org/json/execption/JSONFoundExecption.java: org/json/junit/XMLMyTest.java: Task2 and task5 using library inside run less time than using library outside. We don't need to have a JSON docuemnt to work. This project also admits conversions from other type of files. Secondly, we can also convert from JSON to those type of files. org/json/XML.java: org/json/execption/JSONFoundExecption.java: org/json/junit/XMLMyTest.java: Task2 and task5 using library inside run less time than using library outside. We don't need to have a JSON docuemnt to work. This project also admits conversions from other type of files. Secondly, we can also convert from JSON to those type of files. src/test/java/org/json/junit/XMLMyTestM3.java: src/test/java/org/json/junit/XMLMyTestM3.java: Test two kind of key transformer: key replace and key reverse. And do a key replace in client code VS. inside library Test file position: src/test/java/org/json/junit/XMLMyTestM3.java. In my opinion, First way is more abstract but the code is more elegant.
+Second way is more comprehensive and helpful in understand stream. Test file position: src/test/java/org/json/junit/M4StreamTest.java. Source file position: src/main/java/org/json/JSONObject.javaMilestone 2
-image credit: Ismael Pérez Ortiz
+Summary of Support & Not Support
+toJSONObject(Reader reader, JSONPointer path)
-JSON in Java [package org.json]
-===============================
+support path:
-[](https://mvnrepository.com/artifact/org.json/json)
+```
+JSONObject: /clinical_study/required_header
-**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20211205/json-20211205.jar)**
+JSONArray: /clinical_study/condition_browse/mesh_term
+Index of JSONArray: /clinical_study/condition_browse/mesh_term/1
+```
-# Overview
+not support path:
-[JSON](http://www.JSON.org/) is a light-weight language-independent data interchange format.
+```
+Nested JSONArray: /clinical_study/1/condition_browse/mesh_term/1
+```
-The JSON-Java package is a reference implementation that demonstrates how to parse JSON documents into Java objects and how to generate new JSON documents from the Java classes.
+toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
-Project goals include:
-* Reliable and consistent results
-* Adherence to the JSON specification
-* Easy to build, use, and include in other projects
-* No external dependencies
-* Fast execution and low memory footprint
-* Maintain backward compatibility
-* Designed and tested to use on Java versions 1.6 - 1.11
+support path:
-The files in this package implement JSON encoders and decoders. The package can also convert between JSON and XML, HTTP headers, Cookies, and CDL.
+```
+JSONObject: /clinical_study/required_header
-The license includes this restriction: ["The software shall be used for good, not evil."](https://en.wikipedia.org/wiki/Douglas_Crockford#%22Good,_not_Evil%22) If your conscience cannot live with that, then choose a different package.
+JSONArray: /clinical_study/condition_browse/mesh_term
+```
-# If you would like to contribute to this project
+not support path:
-For more information on contributions, please see [CONTRIBUTING.md](https://github.com/stleary/JSON-java/blob/master/docs/CONTRIBUTING.md)
+```
+Index of JSONArray: /clinical_study/condition_browse/mesh_term/1
+```
-Bug fixes, code improvements, and unit test coverage changes are welcome! Because this project is currently in the maintenance phase, the kinds of changes that can be accepted are limited. For more information, please read the [FAQ](https://github.com/stleary/JSON-java/wiki/FAQ).
+List of Functions
+Test Units (Junit)
+Test Result (Issue537.xml)
-````
-import org.json.JSONObject;
-public class Test {
- public static void main(String args[]){
- JSONObject jo = new JSONObject("{ \"abc\" : \"def\" }");
- System.out.println(jo.toString());
- }
-}
-````
+Part 1: Implementations functions
-
-**Tools to build the package and execute the unit tests**
+static JSONObject toJSONObject(Reader reader, JSONPointer path)
-Execute the test suite with Maven:
```
-mvn clean test
+ /**
+ * milestone 2
+ * Read an XML file into a JSON object, and extract some smaller sub-object inside,
+ * given a certain path (use JSONPointer).
+ * @param reader
+ * The source string.
+ * @param path Configuration options for the parser.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException Thrown if there is an errors while parsing the string
+ */
+ public static Object toJSONObject(Reader reader, JSONPointer path) {
+ try {
+ getJsonObjectWithPath(reader, path, null);
+ } catch (JSONFoundExecption e) {
+ System.out.println(e.getMessage());
+ if (e.getCode().equals("200")) {
+ return e.getJsonObject();
+ }
+ }
+ return null;
+ }
+```
+```
+ /*
+ *
+ * @param level: JSON level depth
+ * @param pLevel: path level depth
+ * @param replace: JSONObject
+ * */
+ private static JSONObject getJsonObjectWithPath(Reader reader, JSONPointer path, JSONObject replace) throws JSONFoundExecption {
+ JSONObject jo = new JSONObject();
+ XMLTokener x = new XMLTokener(reader);
+ String[] paths = path.toString().split("/");
+ paths = Arrays.copyOfRange(paths, 1, paths.length);
+
+ while (x.more()) {
+ x.skipPast("<");
+ if (x.more()) {
+ parseWithPath(x, jo, null, XMLParserConfiguration.ORIGINAL, paths, 0, 0, replace);
+ }
+ }
+ return jo;
+ }
+```
+```
+ private static boolean parseWithPath(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, String[] paths, int level, int pLevel, JSONObject replacement)
+ throws JSONException, JSONFoundExecption{
+ if (token == BANG) {
+ } else if (c == '[') {
+ } else if (token == QUEST) {
+ } else if (token == SLASH) {
+ } else if (token instanceof Character) {
+ } else {
+
+ //add by Sunsheng Su
+ if(level == pLevel){
+ if(paths[pLevel].equals(tagName)){
+ if(pLevel < paths.length-1){
+ pLevel++;
+ }
+
+ //for toJSONObject with replacement
+ if(replacement != null && pLevel == level){ //paths.length -1
+ x.skipPast("" +tagName+ ">");
+ //from professor Cristina test demo and responses to Justin, replacement has the last key of paths
+ context.put(tagName, replacement.get(tagName));
+ return false;
+ }
+ }
+ else if(replacement == null){
+ x.skipPast("" +tagName+ ">");
+ return false;
+ }
+ }
+
+ for (;;){
+ if (token == null) {
+ if (token instanceof String) {
+ } else if (token == SLASH) {
+ } else if (token == GT) {
+ for (;;) {
+ if (token == null) {
+ } else if (token instanceof String) {
+ } else if (token == LT) {
+ if (parseWithPath(x, jsonObject, tagName, config, paths, level+1, pLevel, replacement)) {
+ if (config.getForceList().contains(tagName)) {
+ } else {
+ }
+
+ /*add by Sunsheng Su
+ pLevel == path.length-1 (no need)
+ pLevel not equal to level unless pLevel reach the last one
+ this block code only executed when tagName has been found totally, including children
+ */
+ if(replacement == null && pLevel == paths.length-1 && level == pLevel-1){
+ //for normal path, , like /a/b/c, this is b level and to get tagName c
+ if (paths[pLevel].split("[^0-9]").length != 1){
+ throw new JSONFoundExecption( jsonObject.opt(paths[pLevel]));
+ }
+ //for path with index, like /a/b/c/1, this is c level, and accumulate until 1.
+ else{
+ int index = Integer.parseInt(paths[pLevel]);
+ if(index == 0){
+ throw new JSONFoundExecption( jsonObject.opt(config.getcDataTagName()));
+ }
+ else if(context.get(paths[pLevel-1]) instanceof JSONArray){
+ if(context.getJSONArray(paths[pLevel-1]).length() == index+1)
+ throw new JSONFoundExecption( jsonObject.opt(config.getcDataTagName()));
+ }
+ }
+ }
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
```
-Execute the test suite with Gradlew:
+static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
+
+```
+ /**
+ * milestone 2
+ * Read an XML file into a JSON object, replace a sub-object on a certain key path
+ * with another JSON object that you construct,
+ *
+ * @param reader
+ * The source string.
+ * @param path Configuration options for the parser.
+ * @param replacement Configuration options for the parser.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException Thrown if there is an errors while parsing the string
+ */
+ public static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement) {
+
+ JSONObject jo = null;
+ try {
+ jo = getJsonObjectWithPath(reader, path, replacement);
+ } catch (JSONFoundExecption e) {
+ e.printStackTrace();
+ }
+ return jo;
+ }
```
-gradlew clean build test
+
+Part 2: Test methods
+Test toJSONObject(Reader reader, JSONPointer path)
+
```
+ /*
+ * static JSONObject toJSONObject(Reader reader, JSONPointer path)
+ */
+ //not using library
+ @Test
+ public void testToJSONWithReaderAndPointer1() throws IOException {
+ long startTime = System.currentTimeMillis();
+ _testToJSONWithReaderAndPointer(false);
+ long endTime = System.currentTimeMillis(); //get end time
+ System.out.println("testToJSONWithReaderAndPointer1 Run time:" + (endTime - startTime) + "ms");
+ }
+ //using library
+ @Test
+ public void testToJSONWithReaderAndPointer2() throws IOException {
+ long startTime = System.currentTimeMillis();
+ _testToJSONWithReaderAndPointer(true);
+ long endTime = System.currentTimeMillis(); //get end time
+ System.out.println("testToJSONWithReaderAndPointer2 Run time:" + (endTime - startTime) + "ms");
+ }
-# Notes
+ private void _testToJSONWithReaderAndPointer(boolean isInLibrary) throws IOException {
+ Object actual;
+ if (isInLibrary) {
+ //do query inside library
+ actual = XML.toJSONObject(xmlReader, path);
+ write2File(actual, "inLib");
+ } else {
+ //do query outside library
+ actual = path.queryFrom(XML.toJSONObject(xmlReader));
+ write2File(actual, "outLib");
+ }
+// System.out.println(actual == null ? actual : actual.toString());
+ }
+```
-For more information, please see [NOTES.md](https://github.com/stleary/JSON-java/blob/master/docs/NOTES.md)
-# Files
+Test toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
-For more information on files, please see [FILES.md](https://github.com/stleary/JSON-java/blob/master/docs/FILES.md)
+```
+ /*
+ * static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
+ */
+ //not using library
+ @Test
+ public void testToJSONWithReaderAndPointerWithReplace1() throws IOException {
+ long startTime = System.currentTimeMillis();
+ _testToJSONWithReaderAndPointerWithReplace(false);
+ long endTime = System.currentTimeMillis(); //get end time
+ System.out.println("testToJSONWithReaderAndPointerWithReplace1 Run time:" + (endTime - startTime) + "ms");
+ }
+ //using library
+ @Test
+ public void testToJSONWithReaderAndPointerWithReplace2() throws IOException {
+ long startTime = System.currentTimeMillis();
+ _testToJSONWithReaderAndPointerWithReplace(true);
+ long endTime = System.currentTimeMillis(); //get end time
+ System.out.println("testToJSONWithReaderAndPointerWithReplace2 Run time:" + (endTime - startTime) + "ms");
+ }
-# Release history:
+ private void _testToJSONWithReaderAndPointerWithReplace(boolean isInLibrary) throws IOException {
+ Object actual;
+ if (isInLibrary) {
+ //do query inside library
+ actual = XML.toJSONObject(xmlReader, path, replacement);
+ write2File(actual, "replace_inLib");
+ } else {
+ //do query outside library
+ String[] strs = path.toString().split("/");
+ String keyName = strs[strs.length - 1];
+ String parentPath = "";
+ for(int i=1; i{@code
+ * {@code
* & (ampersand) is replaced by &
* < (less than) is replaced by <
* > (greater than) is replaced by >
@@ -281,6 +285,8 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
c = x.next();
if (c == '-') {
if (x.next() == '-') {
+ //denoting this line is annotation
+ //ignore
x.skipPast("-->");
return false;
}
@@ -335,7 +341,7 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
throw x.syntaxError("Misshaped tag");
// Open tag <
-
+ //if token is tagName
} else {
tagName = (String) token;
token = null;
@@ -348,6 +354,8 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
}
// attribute = value
if (token instanceof String) {
+ //why two consecutive String, then =
+ //maybe is loop cause, last loop
string = (String) token;
token = x.nextToken();
if (token == EQ) {
@@ -385,6 +393,7 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
if (nilAttributeFound) {
context.append(tagName, JSONObject.NULL);
} else if (jsonObject.length() > 0) {
+ //in loop
context.append(tagName, jsonObject);
} else {
context.put(tagName, new JSONArray());
@@ -402,7 +411,10 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
} else if (token == GT) {
// Content, between <...> and
+ // after a String, if it is >, then analysis inner content
for (;;) {
+ //loop goal: first time temporally save String, second time put into parent JSONObject
+ //if has nested element, do recursion
token = x.nextContent();
if (token == null) {
if (tagName != null) {
@@ -423,6 +435,9 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
} else if (token == LT) {
// Nested element
+ // new <
+ //when subStruct come across opposite one, subStruct's recursion return true to subStruct
+ //when subStruct has been accumulated, return false to parentis done
if (parse(x, jsonObject, tagName, config)) {
if (config.getForceList().contains(tagName)) {
// Force the value to be an array
@@ -436,15 +451,300 @@ private static boolean parse(XMLTokener x, JSONObject context, String name, XMLP
}
} else {
if (jsonObject.length() == 0) {
+ //let values of same tagName, save as JSONArray
context.accumulate(tagName, "");
} else if (jsonObject.length() == 1
&& jsonObject.opt(config.getcDataTagName()) != null) {
+ //enter into subStruct and then return true, come here when subStruct is {@code
+ * "content" member. Comments, prologs, DTDs, and {@code
* <[ [ ]]>}
* are ignored.
*
@@ -610,7 +910,7 @@ public static JSONObject toJSONObject(String string) throws JSONException {
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
- * "content" member. Comments, prologs, DTDs, and {@code
+ * "content" member. Comments, prologs, DTDs, and {@code
* <[ [ ]]>}
* are ignored.
*
@@ -690,7 +990,7 @@ public static JSONObject toJSONObject(Reader reader, XMLParserConfiguration conf
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
- * "content" member. Comments, prologs, DTDs, and {@code
+ * "content" member. Comments, prologs, DTDs, and {@code
* <[ [ ]]>}
* are ignored.
*
@@ -716,7 +1016,7 @@ public static JSONObject toJSONObject(String string, boolean keepStrings) throws
* name/value pairs and arrays of values. JSON does not does not like to
* distinguish between elements and attributes. Sequences of similar
* elements are represented as JSONArrays. Content text may be placed in a
- * "content" member. Comments, prologs, DTDs, and {@code
+ * "content" member. Comments, prologs, DTDs, and {@code
* <[ [ ]]>}
* are ignored.
*
@@ -733,6 +1033,74 @@ public static JSONObject toJSONObject(String string, XMLParserConfiguration conf
return toJSONObject(new StringReader(string), config);
}
+
+ /**
+ * milestone 2
+ * Read an XML file into a JSON object, and extract some smaller sub-object inside,
+ * given a certain path (use JSONPointer).
+ * @param reader
+ * The source string.
+ * @param path Configuration options for the parser.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException Thrown if there is an errors while parsing the string
+ */
+ public static Object toJSONObject(Reader reader, JSONPointer path) {
+ try {
+ getJsonObjectWithPath(reader, path, null);
+ } catch (JSONFoundExecption e) {
+// System.out.println(e.getMessage());
+ if (e.getCode().equals("200")) {
+ return e.getJsonObject();
+ }
+ }
+ return null;
+ }
+
+ /*
+ *
+ * @param level: JSON level depth
+ * @param pLevel: path level depth
+ * @param replace: JSONObject
+ * */
+ private static JSONObject getJsonObjectWithPath(Reader reader, JSONPointer path, JSONObject replace) throws JSONFoundExecption {
+ JSONObject jo = new JSONObject();
+ XMLTokener x = new XMLTokener(reader);
+ String[] paths = path.toString().split("/");
+ paths = Arrays.copyOfRange(paths, 1, paths.length);
+
+ while (x.more()) {
+ x.skipPast("<");
+ if (x.more()) {
+ parseWithPath(x, jo, null, XMLParserConfiguration.ORIGINAL, paths, 0, 0, replace);
+ }
+ }
+ return jo;
+ }
+
+ /**
+ * milestone 2
+ * Read an XML file into a JSON object, replace a sub-object on a certain key path
+ * with another JSON object that you construct,
+ *
+ * @param reader
+ * The source string.
+ * @param path Configuration options for the parser.
+ * @param replacement Configuration options for the parser.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException Thrown if there is an errors while parsing the string
+ */
+ public static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement) {
+
+ JSONObject jo = null;
+ try {
+ jo = getJsonObjectWithPath(reader, path, replacement);
+ } catch (JSONFoundExecption e) {
+ e.printStackTrace();
+ }
+ return jo;
+ }
+
+
/**
* Convert a JSONObject into a well-formed, element-normal XML string.
*
From 2bc357dc3a03236cd6c89d0d89144e079c40114d Mon Sep 17 00:00:00 2001
From: susunsheng Part 1: Implementations functions
From 343ed72c0757e4df7b798028b9b973ebb35ac0c1 Mon Sep 17 00:00:00 2001
From: susunsheng Test Units (Junit)
Milestone 2
-
-Summary of Support & Not Support
-
-toJSONObject(Reader reader, JSONPointer path)
-
-support path:
-
-```
-JSONObject: /clinical_study/required_header
-
-JSONArray: /clinical_study/condition_browse/mesh_term
-
-Index of JSONArray: /clinical_study/condition_browse/mesh_term/1
-```
-
-not support path:
-
-```
-Nested JSONArray: /clinical_study/1/condition_browse/mesh_term/1
-```
-
-toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
-
-support path:
-
-```
-JSONObject: /clinical_study/required_header
-
-JSONArray: /clinical_study/condition_browse/mesh_term
-```
-
-not support path:
-
-```
-Index of JSONArray: /clinical_study/condition_browse/mesh_term/1
-```
-
-List of Functions
-Test Units (Junit)
-Test Result (Issue537.xml)
-
-Part 1: Implementations functions
-
-static JSONObject toJSONObject(Reader reader, JSONPointer path)
-
-```
- /**
- * milestone 2
- * Read an XML file into a JSON object, and extract some smaller sub-object inside,
- * given a certain path (use JSONPointer).
- * @param reader
- * The source string.
- * @param path Configuration options for the parser.
- * @return A JSONObject containing the structured data from the XML string.
- * @throws JSONException Thrown if there is an errors while parsing the string
- */
- public static Object toJSONObject(Reader reader, JSONPointer path) {
- try {
- getJsonObjectWithPath(reader, path, null);
- } catch (JSONFoundExecption e) {
- System.out.println(e.getMessage());
- if (e.getCode().equals("200")) {
- return e.getJsonObject();
- }
- }
- return null;
- }
-```
-```
- /*
- *
- * @param level: JSON level depth
- * @param pLevel: path level depth
- * @param replace: JSONObject
- * */
- private static JSONObject getJsonObjectWithPath(Reader reader, JSONPointer path, JSONObject replace) throws JSONFoundExecption {
- JSONObject jo = new JSONObject();
- XMLTokener x = new XMLTokener(reader);
- String[] paths = path.toString().split("/");
- paths = Arrays.copyOfRange(paths, 1, paths.length);
-
- while (x.more()) {
- x.skipPast("<");
- if (x.more()) {
- parseWithPath(x, jo, null, XMLParserConfiguration.ORIGINAL, paths, 0, 0, replace);
- }
- }
- return jo;
- }
-```
-```
- private static boolean parseWithPath(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, String[] paths, int level, int pLevel, JSONObject replacement)
- throws JSONException, JSONFoundExecption{
- if (token == BANG) {
- } else if (c == '[') {
- } else if (token == QUEST) {
- } else if (token == SLASH) {
- } else if (token instanceof Character) {
- } else {
-
- //add by Sunsheng Su
- if(level == pLevel){
- if(paths[pLevel].equals(tagName)){
- if(pLevel < paths.length-1){
- pLevel++;
- }
-
- //for toJSONObject with replacement
- if(replacement != null && pLevel == level){ //paths.length -1
- x.skipPast("" +tagName+ ">");
- //from professor Cristina test demo and responses to Justin, replacement has the last key of paths
- context.put(tagName, replacement.get(tagName));
- return false;
- }
- }
- else if(replacement == null){
- x.skipPast("" +tagName+ ">");
- return false;
- }
- }
-
- for (;;){
- if (token == null) {
- if (token instanceof String) {
- } else if (token == SLASH) {
- } else if (token == GT) {
- for (;;) {
- if (token == null) {
- } else if (token instanceof String) {
- } else if (token == LT) {
- if (parseWithPath(x, jsonObject, tagName, config, paths, level+1, pLevel, replacement)) {
- if (config.getForceList().contains(tagName)) {
- } else {
- }
-
- /*add by Sunsheng Su
- pLevel == path.length-1 (no need)
- pLevel not equal to level unless pLevel reach the last one
- this block code only executed when tagName has been found totally, including children
- */
- if(replacement == null && pLevel == paths.length-1 && level == pLevel-1){
- //for normal path, , like /a/b/c, this is b level and to get tagName c
- if (paths[pLevel].split("[^0-9]").length != 1){
- throw new JSONFoundExecption( jsonObject.opt(paths[pLevel]));
- }
- //for path with index, like /a/b/c/1, this is c level, and accumulate until 1.
- else{
- int index = Integer.parseInt(paths[pLevel]);
- if(index == 0){
- throw new JSONFoundExecption( jsonObject.opt(config.getcDataTagName()));
- }
- else if(context.get(paths[pLevel-1]) instanceof JSONArray){
- if(context.getJSONArray(paths[pLevel-1]).length() == index+1)
- throw new JSONFoundExecption( jsonObject.opt(config.getcDataTagName()));
- }
- }
- }
- return false;
- }
- }
- }
- }
- }
- }
- }
-```
-
-
-static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
-
-```
- /**
- * milestone 2
- * Read an XML file into a JSON object, replace a sub-object on a certain key path
- * with another JSON object that you construct,
- *
- * @param reader
- * The source string.
- * @param path Configuration options for the parser.
- * @param replacement Configuration options for the parser.
- * @return A JSONObject containing the structured data from the XML string.
- * @throws JSONException Thrown if there is an errors while parsing the string
- */
- public static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement) {
-
- JSONObject jo = null;
- try {
- jo = getJsonObjectWithPath(reader, path, replacement);
- } catch (JSONFoundExecption e) {
- e.printStackTrace();
- }
- return jo;
- }
-```
-
-Part 2: Test methods
-Test toJSONObject(Reader reader, JSONPointer path)
-
-```
- /*
- * static JSONObject toJSONObject(Reader reader, JSONPointer path)
- */
- //not using library
- @Test
- public void testToJSONWithReaderAndPointer1() throws IOException {
- long startTime = System.currentTimeMillis();
- _testToJSONWithReaderAndPointer(false);
- long endTime = System.currentTimeMillis(); //get end time
- System.out.println("testToJSONWithReaderAndPointer1 Run time:" + (endTime - startTime) + "ms");
- }
- //using library
- @Test
- public void testToJSONWithReaderAndPointer2() throws IOException {
- long startTime = System.currentTimeMillis();
- _testToJSONWithReaderAndPointer(true);
- long endTime = System.currentTimeMillis(); //get end time
- System.out.println("testToJSONWithReaderAndPointer2 Run time:" + (endTime - startTime) + "ms");
- }
-
- private void _testToJSONWithReaderAndPointer(boolean isInLibrary) throws IOException {
- Object actual;
- if (isInLibrary) {
- //do query inside library
- actual = XML.toJSONObject(xmlReader, path);
- write2File(actual, "inLib");
- } else {
- //do query outside library
- actual = path.queryFrom(XML.toJSONObject(xmlReader));
- write2File(actual, "outLib");
- }
-// System.out.println(actual == null ? actual : actual.toString());
- }
-```
-
-
-Test toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
-
-```
- /*
- * static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
- */
- //not using library
- @Test
- public void testToJSONWithReaderAndPointerWithReplace1() throws IOException {
- long startTime = System.currentTimeMillis();
- _testToJSONWithReaderAndPointerWithReplace(false);
- long endTime = System.currentTimeMillis(); //get end time
- System.out.println("testToJSONWithReaderAndPointerWithReplace1 Run time:" + (endTime - startTime) + "ms");
- }
- //using library
- @Test
- public void testToJSONWithReaderAndPointerWithReplace2() throws IOException {
- long startTime = System.currentTimeMillis();
- _testToJSONWithReaderAndPointerWithReplace(true);
- long endTime = System.currentTimeMillis(); //get end time
- System.out.println("testToJSONWithReaderAndPointerWithReplace2 Run time:" + (endTime - startTime) + "ms");
- }
-
- private void _testToJSONWithReaderAndPointerWithReplace(boolean isInLibrary) throws IOException {
- Object actual;
- if (isInLibrary) {
- //do query inside library
- actual = XML.toJSONObject(xmlReader, path, replacement);
- write2File(actual, "replace_inLib");
- } else {
- //do query outside library
- String[] strs = path.toString().split("/");
- String keyName = strs[strs.length - 1];
- String parentPath = "";
- for(int i=1; iSummary of Support & Not Support
+
+toJSONObject(Reader reader, JSONPointer path)
+
+support path:
+
+```
+JSONObject: /clinical_study/required_header
+
+JSONArray: /clinical_study/condition_browse/mesh_term
+
+Index of JSONArray: /clinical_study/condition_browse/mesh_term/1
+```
+
+not support path:
+
+```
+Nested JSONArray: /clinical_study/1/condition_browse/mesh_term/1
+```
+
+toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
+
+support path:
+
+```
+JSONObject: /clinical_study/required_header
+
+JSONArray: /clinical_study/condition_browse/mesh_term
+```
+
+not support path:
+
+```
+Index of JSONArray: /clinical_study/condition_browse/mesh_term/1
+```
+
+List of Functions
+Test Units (Junit)
+Test Result (Issue537.xml)
+
+Part 1: Implementations functions
+
+static JSONObject toJSONObject(Reader reader, JSONPointer path)
+
+```
+ /**
+ * milestone 2
+ * Read an XML file into a JSON object, and extract some smaller sub-object inside,
+ * given a certain path (use JSONPointer).
+ * @param reader
+ * The source string.
+ * @param path Configuration options for the parser.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException Thrown if there is an errors while parsing the string
+ */
+ public static Object toJSONObject(Reader reader, JSONPointer path) {
+ try {
+ getJsonObjectWithPath(reader, path, null);
+ } catch (JSONFoundExecption e) {
+ System.out.println(e.getMessage());
+ if (e.getCode().equals("200")) {
+ return e.getJsonObject();
+ }
+ }
+ return null;
+ }
+```
+```
+ /*
+ *
+ * @param level: JSON level depth
+ * @param pLevel: path level depth
+ * @param replace: JSONObject
+ * */
+ private static JSONObject getJsonObjectWithPath(Reader reader, JSONPointer path, JSONObject replace) throws JSONFoundExecption {
+ JSONObject jo = new JSONObject();
+ XMLTokener x = new XMLTokener(reader);
+ String[] paths = path.toString().split("/");
+ paths = Arrays.copyOfRange(paths, 1, paths.length);
+
+ while (x.more()) {
+ x.skipPast("<");
+ if (x.more()) {
+ parseWithPath(x, jo, null, XMLParserConfiguration.ORIGINAL, paths, 0, 0, replace);
+ }
+ }
+ return jo;
+ }
+```
+```
+ private static boolean parseWithPath(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, String[] paths, int level, int pLevel, JSONObject replacement)
+ throws JSONException, JSONFoundExecption{
+ if (token == BANG) {
+ } else if (c == '[') {
+ } else if (token == QUEST) {
+ } else if (token == SLASH) {
+ } else if (token instanceof Character) {
+ } else {
+
+ //add by Sunsheng Su
+ if(level == pLevel){
+ if(paths[pLevel].equals(tagName)){
+ if(pLevel < paths.length-1){
+ pLevel++;
+ }
+
+ //for toJSONObject with replacement
+ if(replacement != null && pLevel == level){ //paths.length -1
+ x.skipPast("" +tagName+ ">");
+ //from professor Cristina test demo and responses to Justin, replacement has the last key of paths
+ context.put(tagName, replacement.get(tagName));
+ return false;
+ }
+ }
+ else if(replacement == null){
+ x.skipPast("" +tagName+ ">");
+ return false;
+ }
+ }
+
+ for (;;){
+ if (token == null) {
+ if (token instanceof String) {
+ } else if (token == SLASH) {
+ } else if (token == GT) {
+ for (;;) {
+ if (token == null) {
+ } else if (token instanceof String) {
+ } else if (token == LT) {
+ if (parseWithPath(x, jsonObject, tagName, config, paths, level+1, pLevel, replacement)) {
+ if (config.getForceList().contains(tagName)) {
+ } else {
+ }
+
+ /*add by Sunsheng Su
+ pLevel == path.length-1 (no need)
+ pLevel not equal to level unless pLevel reach the last one
+ this block code only executed when tagName has been found totally, including children
+ */
+ if(replacement == null && pLevel == paths.length-1 && level == pLevel-1){
+ //for normal path, , like /a/b/c, this is b level and to get tagName c
+ if (paths[pLevel].split("[^0-9]").length != 1){
+ throw new JSONFoundExecption( jsonObject.opt(paths[pLevel]));
+ }
+ //for path with index, like /a/b/c/1, this is c level, and accumulate until 1.
+ else{
+ int index = Integer.parseInt(paths[pLevel]);
+ if(index == 0){
+ throw new JSONFoundExecption( jsonObject.opt(config.getcDataTagName()));
+ }
+ else if(context.get(paths[pLevel-1]) instanceof JSONArray){
+ if(context.getJSONArray(paths[pLevel-1]).length() == index+1)
+ throw new JSONFoundExecption( jsonObject.opt(config.getcDataTagName()));
+ }
+ }
+ }
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+```
+
+
+static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
+
+```
+ /**
+ * milestone 2
+ * Read an XML file into a JSON object, replace a sub-object on a certain key path
+ * with another JSON object that you construct,
+ *
+ * @param reader
+ * The source string.
+ * @param path Configuration options for the parser.
+ * @param replacement Configuration options for the parser.
+ * @return A JSONObject containing the structured data from the XML string.
+ * @throws JSONException Thrown if there is an errors while parsing the string
+ */
+ public static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement) {
+
+ JSONObject jo = null;
+ try {
+ jo = getJsonObjectWithPath(reader, path, replacement);
+ } catch (JSONFoundExecption e) {
+ e.printStackTrace();
+ }
+ return jo;
+ }
+```
+
+Part 2: Test methods
+Test toJSONObject(Reader reader, JSONPointer path)
+
+```
+ /*
+ * static JSONObject toJSONObject(Reader reader, JSONPointer path)
+ */
+ //not using library
+ @Test
+ public void testToJSONWithReaderAndPointer1() throws IOException {
+ long startTime = System.currentTimeMillis();
+ _testToJSONWithReaderAndPointer(false);
+ long endTime = System.currentTimeMillis(); //get end time
+ System.out.println("testToJSONWithReaderAndPointer1 Run time:" + (endTime - startTime) + "ms");
+ }
+ //using library
+ @Test
+ public void testToJSONWithReaderAndPointer2() throws IOException {
+ long startTime = System.currentTimeMillis();
+ _testToJSONWithReaderAndPointer(true);
+ long endTime = System.currentTimeMillis(); //get end time
+ System.out.println("testToJSONWithReaderAndPointer2 Run time:" + (endTime - startTime) + "ms");
+ }
+
+ private void _testToJSONWithReaderAndPointer(boolean isInLibrary) throws IOException {
+ Object actual;
+ if (isInLibrary) {
+ //do query inside library
+ actual = XML.toJSONObject(xmlReader, path);
+ write2File(actual, "inLib");
+ } else {
+ //do query outside library
+ actual = path.queryFrom(XML.toJSONObject(xmlReader));
+ write2File(actual, "outLib");
+ }
+// System.out.println(actual == null ? actual : actual.toString());
+ }
+```
+
+
+Test toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
+
+```
+ /*
+ * static JSONObject toJSONObject(Reader reader, JSONPointer path, JSONObject replacement)
+ */
+ //not using library
+ @Test
+ public void testToJSONWithReaderAndPointerWithReplace1() throws IOException {
+ long startTime = System.currentTimeMillis();
+ _testToJSONWithReaderAndPointerWithReplace(false);
+ long endTime = System.currentTimeMillis(); //get end time
+ System.out.println("testToJSONWithReaderAndPointerWithReplace1 Run time:" + (endTime - startTime) + "ms");
+ }
+ //using library
+ @Test
+ public void testToJSONWithReaderAndPointerWithReplace2() throws IOException {
+ long startTime = System.currentTimeMillis();
+ _testToJSONWithReaderAndPointerWithReplace(true);
+ long endTime = System.currentTimeMillis(); //get end time
+ System.out.println("testToJSONWithReaderAndPointerWithReplace2 Run time:" + (endTime - startTime) + "ms");
+ }
+
+ private void _testToJSONWithReaderAndPointerWithReplace(boolean isInLibrary) throws IOException {
+ Object actual;
+ if (isInLibrary) {
+ //do query inside library
+ actual = XML.toJSONObject(xmlReader, path, replacement);
+ write2File(actual, "replace_inLib");
+ } else {
+ //do query outside library
+ String[] strs = path.toString().split("/");
+ String keyName = strs[strs.length - 1];
+ String parentPath = "";
+ for(int i=1; iMilestone 3
+
+Overload function "toJSONObject" and "parse".
+
+```
+public static JSONObject toJSONObject(Reader reader, Function keyTransformer);
+
+private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, Function keyTransformer);
+```
+
+
+Maven
+The project is based on Maven.
+Since Milestone 3 uses Function as a parameter, it needs to adjust the jdk to 1.8.
+
+```xml
+Test Units (Junit)
+
+Key replace in client VS. doing it inside the library
+
+| function \ file size | 8K | 250MB | 490MB |
+| --- | --- | --- | --- |
+| testToJSONKeyReplaceInClient | 18ms | 43,045ms | 103,838ms |
+| testToJSONKeyReplaceWithKeyTransformer | 78ms | 33,132ms | 89,854ms |
+
+Function "testToJSONKeyReplaceInClient" replaces key in client code.
+Function "testToJSONKeyReplaceWithKeyTransformer" replaces key in library, not in client code.
+
+From testing result, we can see that for a small file, doing key replace in client code runs faster than doing it inside library.
+But for big files, doing key replace inside library runs much faster than doing it in client code.
+
+I guess that replacing the key in the library by passing a function of KeyTransformer has additional calling consuming time.
+For small files, this calling consuming time is significant. But for big files, it can be trivial.
+
+
+Implement
+
+To execute the task of key transformation, put the function of "keyTransformer" in three places.
+
+1. deals with global tagName for most cases: put keyTransformer inside callback "parse" (tagName meet with pair end tagName).
+
+```
+ if (parse(x, jsonObject, tagName, config, keyTransformer)) {
+ tagName = (String) keyTransformer.apply(tagName);
+ ...
+ }
+```
+
+2. to deal with special xml format, like below
+
+```xml
+2.1 When First token is a String, second token is also a String, and third token is a "=".
+
+Like below xml, first token is "last_update_posted", second token is "type", third token is "="
+
+```xml
+2.2 When it is going to add content of "September 12, 2019" directly to JsonObject "last_update_posted".
+
+Here is to deal with this kind of token tagName "content".
+
+```
+//add "if" predicate logic
+if(jsonObject.length()>0){
+ //put keyTransformer
+ String configTagName = (String) keyTransformer.apply(config.getcDataTagName());
+ jsonObject.accumulate(configTagName,
+ config.isKeepStrings() ? string : stringToValue(string));
+}
+else {
+ jsonObject.accumulate(config.getcDataTagName(),
+ config.isKeepStrings() ? string : stringToValue(string));
+}
+```
+
+By putting keyTransformer in these two places, it can successfully deal with this case and turn it into correct output.
+
+```json
+{
+ "swe262_last_update_posted": {
+ "swe262_type": "Actual",
+ "swe262_content": "September 12, 2019"
+ }
+}
+```
+
From 3cc1201ce6e95224b86b961a33ba5e6eda384ca9 Mon Sep 17 00:00:00 2001
From: susunsheng Milestone 3
-Overload function "toJSONObject" and "parse".
+Read an XML file into a JSON object, and add the prefix "swe262_" to all of its keys.
+Do it by adding an overloaded static method to the XML class with the signature
+
+Overload function "toJSONObject" and "parse".
```
public static JSONObject toJSONObject(Reader reader, Function keyTransformer);
From ec8f2ce9b42e9f78b8965e39c49c8c5ee4f0c82c Mon Sep 17 00:00:00 2001
From: susunsheng 1. deals with global tagName for most cases: put keyTransformer inside callback "parse" (tagName meet with pair end tagName).
```
- if (parse(x, jsonObject, tagName, config, keyTransformer)) {
- tagName = (String) keyTransformer.apply(tagName);
- ...
- }
+if (parse(x, jsonObject, tagName, config, keyTransformer)) {
+ tagName = (String) keyTransformer.apply(tagName);
+ ...
+}
```
2. to deal with special xml format, like below
From 4d992ba8ed93b71bbe4a84053688ecce10791f57 Mon Sep 17 00:00:00 2001
From: susunsheng Test Units (Junit)
-Milestone 4
+
+Add streaming methods to the library that allow the client code to chain operations on JSON nodes.
+
+Streaming methods in:
+
+Test Units in:
+
+Turn the JSONObject to the stream in type of Map.EntryTwo ways of transforming JSONObject to stream
+
+1. Recursive Stream
+
+```
+public Stream2. Spliterator of Stream
+
+```
+public StreamMaven
+The project is based on Maven.
+Since Milestone 4 uses Stream, it needs to adjust the jdk to 1.8.
+
+```xml
+Test Units (Junit)
+
+Implement
+
+1. Recursive Stream
+
+```
+public Stream2. Spliterator
+
+```
+static class JSONObjectSpliterator implements Spliterator
Test file position: src/test/java/org/json/junit/M4StreamTest.java.
- +Test Units Cases: src/test/java/org/json/junit/M4StreamTest.java + +(https://github.com/JoshuaSunsheng/JSON-java/blob/master/src/test/java/org/json/junit/M4StreamTest.java) -Test streams features: +Source file position: src/main/java/org/json/JSONObject.java
- +Streaming methods: src/main/java/org/json/JSONObject.java + +(https://github.com/JoshuaSunsheng/JSON-java/blob/master/src/main/java/org/json/JSONObject.java) -There is two ways to transform JSONObject into stream. +There are two ways to transform JSONObject into stream.