Compare commits

...

57 Commits

Author SHA1 Message Date
Sean Leary
47fb49b6a8 Update for release 20230227 2023-02-27 07:21:11 -06:00
Sean Leary
0df034c9fd Update for release 20230227 2023-02-27 07:20:10 -06:00
Sean Leary
f0a05e6911 Update README.md 2023-02-27 07:17:51 -06:00
Sean Leary
1275f6809d Merge pull request #723 from TamasPergerDWP/master
JSONML should be protected from stack overflow exceptions caused by recursion, resolving #722
2023-02-17 13:47:36 -06:00
Tamas Perger
9234eab00a refactor: make JSONMLParserConfiguration all-args constructor private, enforcing the builder pattern. 2023-02-13 01:09:29 +00:00
Tamas Perger
72f4c3e646 refactor: rename XMLtoJSONMLParserConfiguration to JSONMLParserConfiguration 2023-02-12 01:32:34 +00:00
Tamas Perger
df2d6f8363 fix: introduce optional XMLtoJSONMLParserConfiguration parameter for JSONML.toJSONArray(...) functions, to facilitate max nesting depth override. 2023-02-11 01:52:13 +00:00
Tamas Perger
a6e412bded fix: limit the nesting depth in JSONML
Limit the XML nesting depth for CVE-2022-45688 when using the JsonML transform.
2023-02-10 01:46:44 +00:00
Tamas Perger
2391d248cc fix: amend XMLParserConfiguration.clone() to include the new maxNestingDepth param.
Amend Javadoc for XML and XMLParserConfiguration classes.
2023-02-10 01:45:34 +00:00
Sean Leary
401495ae86 Merge pull request #720 from cleydyr/issue-708
Limit the XML nesting depth for CVE-2022-45688
2023-02-05 19:30:04 -06:00
Cleydyr de Albuquerque
448e204186 docs: remove wrong description of parse method 2023-02-02 20:16:16 +01:00
Cleydyr de Albuquerque
eb56704e68 fix: set default maximum nesting depth as 512 2023-02-02 18:15:03 +01:00
Cleydyr de Albuquerque
651511f500 tests: add new test to verify that an XML having the permitted nesting depth can be converted 2023-02-01 20:22:47 +01:00
Cleydyr de Albuquerque
a14cb12c85 refactor: keep consistence with other tests and tidy up constant 2023-02-01 20:22:32 +01:00
Cleydyr de Albuquerque
f566a1d9ee fix: limit the nesting depth 2023-02-01 16:26:58 +01:00
Sean Leary
5920eca2d7 Merge pull request #711 from 6d64/revert-pull-707-interviewbit-spam
Revert pull 707 - interviewbit spam
2022-11-30 20:20:39 -06:00
6d64
3b097d051a Revert pull 707 - interviewbit spam
Reverted commit that was added by a bot adding interviewbit spam to
repos on github
2022-12-01 03:21:26 +11:00
Sean Leary
4e630e58a4 Merge pull request #707 from ASAlishaa/patch-1
Added new resource to the repos
2022-11-17 19:14:11 -06:00
ASAlisha
b732188e4e Added new resource to this repos.
Added resource in the correct format.
2022-11-15 16:31:05 +05:30
ASAlisha
5369442671 Added new resource to the repos
Added new useful JSON resource.
2022-11-14 03:26:18 +05:30
Sean Leary
bb1138762a Merge pull request #703 from TomerPacific/feature/update-release-for-JSONMap-Change
Update Releases.md for JSONObject(Map): Throws NPE if key is null
2022-11-05 17:39:13 -05:00
Sean Leary
6a732ec99d Merge pull request #704 from niranjanib/fix-javadoc-not-visible-in-website
move javadoc comments above the interface definition to make it visible
2022-11-05 17:38:15 -05:00
Niranjani
c798c76ddd move javadoc comments above the interface definition to make it visible
Fix #670
2022-10-30 22:10:38 +05:30
unknown
23d5e52a53 feature/update-release-for-JSONMap-Change adding breaking change for JSONMap to corresponding release 2022-10-28 08:45:54 +03:00
Sean Leary
98df35449a Merge pull request #696 from bmk15897/fix-flaky-test
Update JSONPointerTest for NonDex compatibility
2022-10-15 08:24:01 -05:00
Sean Leary
1be6ee31a7 Merge pull request #694 from DeaneOC/Pretty-Print-XML-Functionality
Pretty print XML
2022-10-13 21:46:26 -05:00
Bharati Kulkarni
a2d3d3c9b5 Fix Flaky Test 2022-10-11 14:33:43 -05:00
Dean
bf9219386a Merge branch 'master' of https://github.com/stleary/JSON-java into Pretty-Print-XML-Functionality 2022-10-10 11:12:49 +01:00
Dean
85495facbd Corrected test 2022-10-10 11:12:35 +01:00
Dean
7aba3ac941 System line seperator now being used in JUnit test 2022-10-10 11:09:42 +01:00
Sean Leary
d51250f6b0 Merge pull request #692 from InACommandBlock/patch-1
Example.md syntax highlight and indentation
2022-10-09 22:28:36 -05:00
Dean
9cb8e153bf Added JavaDocs 2022-10-07 17:57:07 +01:00
Dean
80c1479ad8 Merge branch 'master' of https://github.com/stleary/JSON-java into Pretty-Print-XML-Functionality 2022-10-07 17:56:54 +01:00
Sean Leary
444335d12a Merge pull request #691 from hendrixjoseph/issue-657-unit-tests-should-check-various-number-formats
create unit tests for various number formats
2022-10-07 11:18:41 -05:00
Dean
a2c0562e04 Removed unused import 2022-10-07 15:04:09 +01:00
Dean
153972afdf Adding resources 2022-10-07 10:35:14 +01:00
Dean
4a8ff28fd8 Reduced Test code length by using resources 2022-10-07 10:35:06 +01:00
Dean
fa457a4113 Test cases for XML toString indentation 2022-10-06 12:01:26 +01:00
Dean
b7f708b222 Altered XML toString to allow indentation param 2022-10-06 12:01:13 +01:00
TheCommandBlock
12411b7981 Update Examples.md
Co-authored-by: JAYSE <104235500+JayseMayne@users.noreply.github.com>
2022-10-06 03:18:03 +02:00
TheCommandBlock
61801c623e Minor Adjustments Example.md
Added syntax highlighting, standardised indentation
2022-10-06 00:48:34 +02:00
hendrixjoseph
1915aab7c4 create unit tests for various number formats 2022-10-04 14:32:41 -04:00
Sean Leary
8439039da7 Update pom.xml
For the 20220924 release
2022-09-24 16:25:18 -05:00
Sean Leary
a6bdd081eb Update RELEASES.md 2022-09-24 16:13:11 -05:00
Sean Leary
a30d71fdca Update README.md 2022-09-24 16:11:12 -05:00
Sean Leary
cdd67b0aef Merge pull request #688 from stleary/update-copyright
#688 update copyright
2022-08-26 21:07:52 -05:00
stleary
89f6e7f6a6 Merge branch 'master' into update-copyright 2022-08-26 20:59:00 -05:00
Sean Leary
346fb26f2d Merge pull request #683 from spaffrath/Issue_682_JSONString_similarity
Issue 682 JSONString similarity
2022-08-26 20:57:22 -05:00
stleary
6daabb43ab update-copyright - Replace copyright and license restrictions with Public Domain 2022-08-23 20:00:25 -05:00
Sean Leary
57f785c42e Merge pull request #687 from schw1804/patch-1
Fix typo
2022-08-23 17:13:10 -05:00
Joshua Schwartz
3eecd67a3b Fix typo 2022-08-23 15:00:01 -05:00
Sean Leary
5a587bbdfd Merge pull request #685 from stleary/map-unit-tests
JSONObject map type unit tests
2022-08-23 07:59:35 -05:00
stleary
e0534b3ec7 initial attempt to test for inconsistent map types in JSONObject 2022-08-20 16:14:34 -05:00
spaffrath
7dd9e01dae Merge branch 'stleary:master' into Issue_682_JSONString_similarity 2022-08-20 07:51:30 -07:00
Sean Leary
88ca19042b Merge pull request #684 from stleary/pipeline-fix-1
pipeline-fix-1 remove v7 build from pipeline
2022-08-20 08:33:23 -05:00
stleary
b4036e6a8e pipeline-fix-1 remove v7 build from pipeline 2022-08-13 12:50:10 -05:00
Scott Paffrath
89f16ad0af Issue 682 JSONString similarity 2022-08-05 11:00:33 -07:00
49 changed files with 3243 additions and 1397 deletions

View File

@@ -42,7 +42,7 @@ jobs:
strategy:
matrix:
# build against supported Java LTS versions:
java: [ 1.7, 8, 11 ]
java: [ 8, 11 ]
name: Java ${{ matrix.java }}
steps:
- uses: actions/checkout@v2

View File

@@ -1,7 +1,7 @@
<h1>Examples</h1>
<p>Imports used in the examples: </p>
```
```java
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
@@ -14,353 +14,353 @@ import java.util.Properties;
<h3>Using JSONArray</h3>
```
private static void JSONExampleArray1() {
//We create a JSONObject from a String containing an array using JSONArray
//Firstly, we declare an Array in a String
```java
private static void JSONExampleArray1() {
//We create a JSONObject from a String containing an array using JSONArray
//Firstly, we declare an Array in a String
String arrayStr =
"["+"true,"+"false,"+ "\"true\","+ "\"false\","+"\"hello\","+"23.45e-4,"+
"\"23.45\","+"42,"+"\"43\","+"["+"\"world\""+"],"+
"{"+
"\"key1\":\"value1\","+
"\"key2\":\"value2\","+
"\"key3\":\"value3\","+
"\"key4\":\"value4\""+
"},"+
"0,"+"\"-1\""+
"]";
String arrayStr =
"["+"true,"+"false,"+ "\"true\","+ "\"false\","+"\"hello\","+"23.45e-4,"+
"\"23.45\","+"42,"+"\"43\","+"["+"\"world\""+"],"+
"{"+
"\"key1\":\"value1\","+
"\"key2\":\"value2\","+
"\"key3\":\"value3\","+
"\"key4\":\"value4\""+
"},"+
"0,"+"\"-1\""+
"]";
//Then, we initializate the JSONArray thanks to its constructor
//Then, we initializate the JSONArray thanks to its constructor
JSONArray array = new JSONArray(arrayStr);
System.out.println("Values array: "+ array);
JSONArray array = new JSONArray(arrayStr);
System.out.println("Values array: "+ array);
//We convert that array into a JSONObject, but first, we need the labels, so we need another JSONArray with the labels.
//Here we will use an auxiliary function to get one for the example.
//We convert that array into a JSONObject, but first, we need the labels, so we need another JSONArray with the labels.
//Here we will use an auxiliary function to get one for the example.
JSONArray list = listNumberArray(array.length());
System.out.println("Label Array: "+ list.toString());
//Now, we construct the JSONObject using both the value array and the label array.
JSONObject object = array.toJSONObject(list);
System.out.println("Final JSONOBject: " + object);
}
//This method creates an JSONArray of labels in which those are generated by their positions
private static JSONArray listNumberArray(int max){
JSONArray res = new JSONArray();
for (int i=0; i<max;i++) {
//The value of the labels must be an String in order to make it work
res.put(String.valueOf(i));
}
return res;
JSONArray list = listNumberArray(array.length());
System.out.println("Label Array: "+ list.toString());
//Now, we construct the JSONObject using both the value array and the label array.
JSONObject object = array.toJSONObject(list);
System.out.println("Final JSONOBject: " + object);
}
//This method creates an JSONArray of labels in which those are generated by their positions
private static JSONArray listNumberArray(int max){
JSONArray res = new JSONArray();
for (int i=0; i<max;i++) {
//The value of the labels must be an String in order to make it work
res.put(String.valueOf(i));
}
return res;
}
```
```
private static void JSONExampleArray2() {
```java
private static void JSONExampleArray2() {
//We can also create an Array without a String by creating an empty array and adding elements to it
//We can also create an Array without a String by creating an empty array and adding elements to it
JSONArray array = new JSONArray();
JSONArray array = new JSONArray();
//Adding elements with .put()
//Adding elements with .put()
array.put("value");
array.put(5);
array.put(-23.45e67);
array.put(true);
//We convert it to JSONObject providing a label arrray like last time
array.put("value");
array.put(5);
array.put(-23.45e67);
array.put(true);
JSONArray list = listNumberArray(array.length());
JSONObject object = array.toJSONObject(list);
System.out.println("Final JSONOBject: " + object);
}
//We convert it to JSONObject providing a label arrray like last time
JSONArray list = listNumberArray(array.length());
JSONObject object = array.toJSONObject(list);
System.out.println("Final JSONOBject: " + object);
}
```
<h3>Using JSONStringer</h3>
```
private static void JSONExampleStringer() {
```java
private static void JSONExampleStringer() {
//We initializate the JSONStringer
//We initializate the JSONStringer
JSONStringer jsonStringer = new JSONStringer();
JSONStringer jsonStringer = new JSONStringer();
//Now we start the process of adding elements with .object()
//Now we start the process of adding elements with .object()
jsonStringer.object();
jsonStringer.object();
//We can now add elements as keys and values with .values () and .key()
//We can now add elements as keys and values with .values () and .key()
jsonStringer.key("trueValue").value(true);
jsonStringer.key("falseValue").value(false);
jsonStringer.key("nullValue").value(null);
jsonStringer.key("stringValue").value("hello world!");
jsonStringer.key("complexStringValue").value("h\be\tllo w\u1234orld!");
jsonStringer.key("intValue").value(42);
jsonStringer.key("doubleValue").value(-23.45e67);
jsonStringer.key("trueValue").value(true);
jsonStringer.key("falseValue").value(false);
jsonStringer.key("nullValue").value(null);
jsonStringer.key("stringValue").value("hello world!");
jsonStringer.key("complexStringValue").value("h\be\tllo w\u1234orld!");
jsonStringer.key("intValue").value(42);
jsonStringer.key("doubleValue").value(-23.45e67);
//We end this prcedure with .ednObject
//We end this prcedure with .ednObject
jsonStringer.endObject();
jsonStringer.endObject();
//Once we have a JSONStringer, we convert it to JSONObject generating a String and using JSONObject's contructor.
//Once we have a JSONStringer, we convert it to JSONObject generating a String and using JSONObject's contructor.
String str = jsonStringer.toString();
JSONObject jsonObject = new JSONObject(str);
System.out.println("Final JSONOBject: " + jsonObject);
}
String str = jsonStringer.toString();
JSONObject jsonObject = new JSONObject(str);
System.out.println("Final JSONOBject: " + jsonObject);
}
```
<h3>Using JSONObject</h3>
```java
private static void JSONExampleObject1() {
//We can create a JSONObject from a String with the class builder
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
System.out.println("Final JSONObject: " + example);
}
```
private static void JSONExampleObject1() {
```java
private static void JSONExampleObject2() {
//We can create a JSONObject from a String with the class builder
//We can also create a JSONObject directly without messing around with any of the other functions.
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
System.out.println("Final JSONObject: " + example);
}
JSONObject example = new JSONObject();
//Now we add the keys and values in a similar way as the Stringer method
example.put("key", "value");
//As you can see, the first entry is the key and the second would be its associeted value.
example.put("key2", 5);
example.put("key3", -23.45e67);
example.put("trueValue", true);
//We can't add null values thougth
//example.put("nullValue", null); //This is not possible
System.out.println("Final JSONOBject: " + example);
}
```
```
private static void JSONExampleObject2() {
```java
private static void JSONExampleObject3() {
//We can also create a JSONObject directly without messing around with any of the other functions.
//We can also create a JSONObject with a Java Map
//YoU will need a Map whose keys are Strings. The values can be whatever you want
JSONObject example = new JSONObject();
Map<String,Double> map = new HashMap<String, Double>();
map.put("key1", 1.0);
map.put("key2", -23.45e67);
//Now we add the keys and values in a similar way as the Stringer method
example.put("key", "value");
//We create the JSONObject with the map with its class builder
//As you can see, the first entry is the key and the second would be its associeted value.
example.put("key2", 5);
example.put("key3", -23.45e67);
example.put("trueValue", true);
//We can't add null values thougth
//example.put("nullValue", null); //This is not possible
System.out.println("Final JSONOBject: " + example);
}
```
```
private static void JSONExampleObject3() {
//We can also create a JSONObject with a Java Map
//YoU will need a Map whose keys are Strings. The values can be whatever you want
Map<String,Double> map = new HashMap<String, Double>();
map.put("key1", 1.0);
map.put("key2", -23.45e67);
//We create the JSONObject with the map with its class builder
JSONObject example = new JSONObject(map);
System.out.println("Final JSONOBject: " + example);
}
JSONObject example = new JSONObject(map);
System.out.println("Final JSONOBject: " + example);
}
```
<h3>Using JSONWriter</h3>
```
private static void JSONExamplWriter() {
```java
private static void JSONExamplWriter() {
//This method works in a very similar way to Object and Stringer in the construction of the JSON.
//The difference is that it needs a Java object called "Appendable" like StringBuilder
//This method works in a very similar way to Object and Stringer in the construction of the JSON.
//The difference is that it needs a Java object called "Appendable" like StringBuilder
StringBuilder write = new StringBuilder();
JSONWriter jsonWriter = new JSONWriter(write);
StringBuilder write = new StringBuilder();
JSONWriter jsonWriter = new JSONWriter(write);
//We behave now the same way as Stringer
//We behave now the same way as Stringer
jsonWriter.object();
jsonWriter.key("trueValue").value(true);
jsonWriter.key("falseValue").value(false);
jsonWriter.key("nullValue").value(null);
jsonWriter.key("stringValue").value("hello world!");
jsonWriter.key("complexStringValue").value("h\be\tllo w\u1234orld!");
jsonWriter.key("intValue").value(42);
jsonWriter.key("doubleValue").value(-23.45e67);
jsonWriter.endObject();
//The resoult should be in the "write" object
System.out.println("JSON: " + write.toString());
//The difference is that we don't get a JSONObject in this one.
}
jsonWriter.object();
jsonWriter.key("trueValue").value(true);
jsonWriter.key("falseValue").value(false);
jsonWriter.key("nullValue").value(null);
jsonWriter.key("stringValue").value("hello world!");
jsonWriter.key("complexStringValue").value("h\be\tllo w\u1234orld!");
jsonWriter.key("intValue").value(42);
jsonWriter.key("doubleValue").value(-23.45e67);
jsonWriter.endObject();
//The resoult should be in the "write" object
System.out.println("JSON: " + write.toString());
//The difference is that we don't get a JSONObject in this one.
}
```
```
private static void JSONExampleTokener() {
```java
private static void JSONExampleTokener() {
//A partir de una String podemos crear un JSONTokener, que lo podemos usar alternativamente para JSONArray,JSONObject
//A partir de una String podemos crear un JSONTokener, que lo podemos usar alternativamente para JSONArray,JSONObject
String string = "this is not a valid JSON string";
JSONTokener token = new JSONTokener(string);
//Now you can use the token in JSONObject and Array the same way as a String
String string = "this is not a valid JSON string";
JSONTokener token = new JSONTokener(string);
JSONObject object = new JSONObject(token);
JSONArray array = new JSONArray(token);
}
//Now you can use the token in JSONObject and Array the same way as a String
JSONObject object = new JSONObject(token);
JSONArray array = new JSONArray(token);
}
```
<h2>Part 2: Conversion methods</h2>
<p>We don't need to have a JSON docuemnt to work. This project also admits conversions from other type of files.</p>
<p>We don't need to have a JSON document to work. This project also admits conversions from other type of files.</p>
<p>Secondly, we can also convert from JSON to those type of files.</p>
<h3>Extra: Conversion to JSONArray</h3>
```
private static void JSONObjectToArray() {
//We start with a JSONObject
```java
private static void JSONObjectToArray() {
//We start with a JSONObject
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
//We need a list of key strings like the reverse operation
JSONArray keyStrings = listNumberArray(example.length());
//Then we convert to the Array using both elelements
JSONArray array = example.toJSONArray(keyStrings);
System.out.println("Final JSONArray: " + array);
}
JSONObject example = new JSONObject(string);
//We need a list of key strings like the reverse operation
JSONArray keyStrings = listNumberArray(example.length());
//Then we convert to the Array using both elelements
JSONArray array = example.toJSONArray(keyStrings);
System.out.println("Final JSONArray: " + array);
}
```
<h3>XML Conversions</h3>
```
private static void XMLToExampleConversion() {
```java
private static void XMLToExampleConversion() {
//We start with a JSONObject
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
//We start with a JSONObject
//We obtain a String with XML format with toString()
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
String output = XML.toString(example);
System.out.println("Final XML: " + output);
}
//We obtain a String with XML format with toString()
String output = XML.toString(example);
System.out.println("Final XML: " + output);
}
```
```
private static void XMLFromExampleConversion() {
```java
private static void XMLFromExampleConversion() {
//We start with a string with the XML format
//We start with a string with the XML format
String string = "<0>value</0><1>5</1><2>-2.345E+68</2><3>true</3>";
String string = "<0>value</0><1>5</1><2>-2.345E+68</2><3>true</3>";
//We obtain a JSONObject with toJSONOBject()
//We obtain a JSONObject with toJSONOBject()
JSONObject output = XML.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
JSONObject output = XML.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
```
<h3>Cookie Conversions</h3>
```java
private static void CookieToExampleConversion() {
//We start with a JSONObject
//The JSONOBject needs to entries that gives the cookie a name and gives the field "name" a name too.
//The Cokkie format doesn't support booleans
String string = "{\"name\":\"Cookie-Name\",\"value\":\"name\",\"1\":5,\"2\":-2.345E68,\"3\":'true'}";
JSONObject example = new JSONObject(string);
//We obtain a String with Cookie format with toString()
String output = Cookie.toString(example);
System.out.println("Final Cookie: " + output);
}
```
private static void CookieToExampleConversion() {
```java
private static void CookieFromExampleConversion() {
//We start with a JSONObject
//The JSONOBject needs to entries that gives the cookie a name and gives the field "name" a name too.
//The Cokkie format doesn't support booleans
//We start with a string with the Cookie format
String string = "{\"name\":\"Cookie-Name\",\"value\":\"name\",\"1\":5,\"2\":-2.345E68,\"3\":'true'}";
JSONObject example = new JSONObject(string);
//We obtain a String with Cookie format with toString()
String string = "Cookie-Name=name;1=5;2=-2.345E%2b68;3=true";
String output = Cookie.toString(example);
System.out.println("Final Cookie: " + output);
}
```
```
private static void CookieFromExampleConversion() {
//We obtain a JSONObject with toJSONOBject()
//We start with a string with the Cookie format
String string = "Cookie-Name=name;1=5;2=-2.345E%2b68;3=true";
//We obtain a JSONObject with toJSONOBject()
JSONObject output = Cookie.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
JSONObject output = Cookie.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
```
<h3>HTTP Conversions</h3>
```java
private static void HTTPToExampleConversion() {
//We start with a JSONObject
//The JSONObject must have the minimun header for a HTTP request or header
String string = "{\"Method\":\"POST\",\"Request-URI\":'/',\"HTTP-Version\":'HTTP/1.1',\"Value1\":true,\"Value2\":2,\"Value3\":-2.345E68}";
JSONObject example = new JSONObject(string);
//We obtain a String with HTTP format with toString()
String output = HTTP.toString(example);
System.out.println("Final HTTP: " + output);
}
```
private static void HTTPToExampleConversion() {
```java
private static void HTTPFromExampleConversion() {
//We start with a JSONObject
//The JSONObject must have the minimun header for a HTTP request or header
//We start with a string with the HTTP format
String string = "{\"Method\":\"POST\",\"Request-URI\":'/',\"HTTP-Version\":'HTTP/1.1',\"Value1\":true,\"Value2\":2,\"Value3\":-2.345E68}";
String string = "Final HTTP: POST '/' HTTP/1.1 Value3: -2.345E+68 Value1: true Value2: 2";
JSONObject example = new JSONObject(string);
//We obtain a JSONObject with toJSONOBject()
//We obtain a String with HTTP format with toString()
String output = HTTP.toString(example);
System.out.println("Final HTTP: " + output);
}
```
```
private static void HTTPFromExampleConversion() {
//We start with a string with the HTTP format
String string = "Final HTTP: POST '/' HTTP/1.1 Value3: -2.345E+68 Value1: true Value2: 2";
//We obtain a JSONObject with toJSONOBject()
JSONObject output = HTTP.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
JSONObject output = HTTP.toJSONObject(string);
System.out.println("Final JSONObject: " + output);
}
```
<h3>CDL Conversions</h3>
```
```java
private static void CDLToExampleConversion() {
//We start with some JSONObjects with the same values in the keys but different values in the "values"
//We start with some JSONObjects with the same values in the keys but different values in the "values"
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
String string2 = "{\"0\":\"value2\",\"1\":6,\"2\":-8.345E68,\"3\":false}";
JSONObject example2 = new JSONObject(string2);
//We need now a JSONArray with those JSONObjects
String string = "{\"0\":\"value\",\"1\":5,\"2\":-2.345E68,\"3\":true}";
JSONObject example = new JSONObject(string);
JSONArray array = new JSONArray();
array.put(example);
array.put(example2);
String string2 = "{\"0\":\"value2\",\"1\":6,\"2\":-8.345E68,\"3\":false}";
JSONObject example2 = new JSONObject(string2);
//We obtain a String with XML format with toString()
//We need now a JSONArray with those JSONObjects
String output = CDL.toString(array);
System.out.println("Final CDL: \r\n" + output);
}
```
JSONArray array = new JSONArray();
array.put(example);
array.put(example2);
//We obtain a String with XML format with toString()
String output = CDL.toString(array);
System.out.println("Final CDL: \r\n" + output);
}
```
```java
private static void CDLFromExampleConversion() {
//We start wtih a String with the CDL format
@@ -368,7 +368,7 @@ private static void CDLFromExampleConversion() {
String string = "0,1,2,3\n"
+ "value,5,-2.345E+68,true\n"
+ "value2,6,-8.345E+68,false";
//We obtain a JSONArray with toJSONOBject()
JSONArray output = CDL.toJSONArray(string);
@@ -377,8 +377,8 @@ private static void CDLFromExampleConversion() {
```
<h3>Properties Conversions</h3>
```
private static Properties PropertyToExampleConversion() {
```java
private static Properties PropertyToExampleConversion() {
//We start with a JSONObject
@@ -391,43 +391,43 @@ private static void CDLFromExampleConversion() {
System.out.println("Final Properties: " + output);
return output;
}
}
```
```
private static void PropertyFromExampleConversion() {
```java
private static void PropertyFromExampleConversion() {
//We start with a Properties object
//We start with a Properties object
Properties input = PropertyToExampleConversion();
Properties input = PropertyToExampleConversion();
//We obtain a JSONObject with toJSONOBject()
//We obtain a JSONObject with toJSONOBject()
JSONObject output = Property.toJSONObject(input);
System.out.println("Final JSONObject: " + output);
}
JSONObject output = Property.toJSONObject(input);
System.out.println("Final JSONObject: " + output);
}
```
<h2>List of all examples methods</h2>
<h2>List of all examples methods</h2>
```
public static void main(String[] args) {
//JSONObjectToArray();
//JSONExampleArray1();
//JSONExampleArray2();
//JSONExampleStringer();
//JSONExampleObject1();
//JSONExampleObject2();
//JSONExampleObject3();
//JSONExamplWriter();
//XMLToExampleConversion();
//XMLFromExampleConversion();
//CookieToExampleConversion();
//CookieFromExampleConversion();
//HTTPToExampleConversion();
//HTTPFromExampleConversion();
//CDLToExampleConversion();
//CDLFromExampleConversion();
//PropertyToExampleConversion();
//PropertyFromExampleConversion();
}
```java
public static void main(String[] args) {
//JSONObjectToArray();
//JSONExampleArray1();
//JSONExampleArray2();
//JSONExampleStringer();
//JSONExampleObject1();
//JSONExampleObject2();
//JSONExampleObject3();
//JSONExamplWriter();
//XMLToExampleConversion();
//XMLFromExampleConversion();
//CookieToExampleConversion();
//CookieFromExampleConversion();
//HTTPToExampleConversion();
//HTTPFromExampleConversion();
//CDLToExampleConversion();
//CDLFromExampleConversion();
//PropertyToExampleConversion();
//PropertyFromExampleConversion();
}
```

23
LICENSE
View File

@@ -1,23 +1,2 @@
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.

View File

@@ -8,7 +8,7 @@ JSON in Java [package org.json]
[![Maven Central](https://img.shields.io/maven-central/v/org.json/json.svg)](https://mvnrepository.com/artifact/org.json/json)
**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20220320/json-20220320.jar)**
**[Click here if you just want the latest release jar file.](https://search.maven.org/remotecontent?filepath=org/json/json/20230227/json-20230227.jar)**
# Overview
@@ -28,8 +28,6 @@ Project goals include:
The files in this package implement JSON encoders and decoders. The package can also convert between JSON and XML, HTTP headers, Cookies, and CDL.
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.
# If you would like to contribute to this project
For more information on contributions, please see [CONTRIBUTING.md](https://github.com/stleary/JSON-java/blob/master/docs/CONTRIBUTING.md)

View File

@@ -5,6 +5,10 @@ and artifactId "json". For example:
[https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav](https://search.maven.org/search?q=g:org.json%20AND%20a:json&core=gav)
~~~
20230227 Fix for CVE-2022-45688 and recent commits
20220924 New License - public domain, and some minor updates
20220320 Wrap StackOverflow with JSONException
20211205 Recent commits and some bug fixes for similar()
@@ -18,6 +22,7 @@ and artifactId "json". For example:
20190722 Recent commits
20180813 POM change to include Automatic-Module-Name (#431)
JSONObject(Map) now throws an exception if any of a map keys are null (#405)
20180130 Recent commits

29
pom.xml
View File

@@ -3,7 +3,7 @@
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20220320</version>
<version>20230227</version>
<packaging>bundle</packaging>
<name>JSON in Java</name>
@@ -18,10 +18,6 @@
This is a reference implementation. There is a large number of JSON packages
in Java. Perhaps someday the Java community will standardize on one. Until
then, choose carefully.
The license includes this restriction: "The software shall be used for good,
not evil." If your conscience cannot live with that, then choose a different
package.
</description>
<url>https://github.com/douglascrockford/JSON-java</url>
@@ -39,28 +35,9 @@
<licenses>
<license>
<name>The JSON License</name>
<url>http://json.org/license.html</url>
<name>Public Domain</name>
<url>https://github.com/stleary/JSON-java/blob/master/LICENSE</url>
<distribution>repo</distribution>
<comments>Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</comments>
</license>
</licenses>

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -3,27 +3,7 @@ package org.json;
import java.util.Locale;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.util.Locale;

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.io.IOException;
@@ -1386,6 +1366,10 @@ public class JSONArray implements Iterable<Object> {
if (!JSONObject.isNumberSimilar((Number)valueThis, (Number)valueOther)) {
return false;
}
} else if (valueThis instanceof JSONString && valueOther instanceof JSONString) {
if (!((JSONString) valueThis).toJSONString().equals(((JSONString) valueOther).toJSONString())) {
return false;
}
} else if (!valueThis.equals(valueOther)) {
return false;
}

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2008 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**
@@ -47,7 +27,32 @@ public class JSONML {
XMLTokener x,
boolean arrayForm,
JSONArray ja,
boolean keepStrings
boolean keepStrings,
int currentNestingDepth
) throws JSONException {
return parse(x,arrayForm, ja,
keepStrings ? JSONMLParserConfiguration.KEEP_STRINGS : JSONMLParserConfiguration.ORIGINAL,
currentNestingDepth);
}
/**
* Parse XML values and store them in a JSONArray.
* @param x The XMLTokener containing the source string.
* @param arrayForm true if array form, false if object form.
* @param ja The JSONArray that is containing the current tag or null
* if we are at the outermost level.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means Don't type-convert text nodes and attribute values.
* @return A JSONArray if the value is the outermost tag, otherwise null.
* @throws JSONException if a parsing error occurs
*/
private static Object parse(
XMLTokener x,
boolean arrayForm,
JSONArray ja,
JSONMLParserConfiguration config,
int currentNestingDepth
) throws JSONException {
String attribute;
char c;
@@ -172,7 +177,7 @@ public class JSONML {
if (!(token instanceof String)) {
throw x.syntaxError("Missing value");
}
newjo.accumulate(attribute, keepStrings ? ((String)token) :XML.stringToValue((String)token));
newjo.accumulate(attribute, config.isKeepStrings() ? ((String)token) :XML.stringToValue((String)token));
token = null;
} else {
newjo.accumulate(attribute, "");
@@ -201,7 +206,12 @@ public class JSONML {
if (token != XML.GT) {
throw x.syntaxError("Misshaped tag");
}
closeTag = (String)parse(x, arrayForm, newja, keepStrings);
if (currentNestingDepth == config.getMaxNestingDepth()) {
throw x.syntaxError("Maximum nesting depth of " + config.getMaxNestingDepth() + " reached");
}
closeTag = (String)parse(x, arrayForm, newja, config, currentNestingDepth + 1);
if (closeTag != null) {
if (!closeTag.equals(tagName)) {
throw x.syntaxError("Mismatched '" + tagName +
@@ -223,7 +233,7 @@ public class JSONML {
} else {
if (ja != null) {
ja.put(token instanceof String
? keepStrings ? XML.unescape((String)token) :XML.stringToValue((String)token)
? (config.isKeepStrings() ? XML.unescape((String)token) : XML.stringToValue((String)token))
: token);
}
}
@@ -244,7 +254,7 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(String string) throws JSONException {
return (JSONArray)parse(new XMLTokener(string), true, null, false);
return (JSONArray)parse(new XMLTokener(string), true, null, JSONMLParserConfiguration.ORIGINAL, 0);
}
@@ -255,8 +265,8 @@ public class JSONML {
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child tags.
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* but just leaves it as a string.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The source string.
@@ -266,7 +276,32 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(String string, boolean keepStrings) throws JSONException {
return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings);
return (JSONArray)parse(new XMLTokener(string), true, null, keepStrings, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONArray using the JsonML transform. Each XML tag is represented as
* a JSONArray in which the first element is the tag name. If the tag has
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child tags.
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* but just leaves it as a string.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The source string.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONArray containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(String string, JSONMLParserConfiguration config) throws JSONException {
return (JSONArray)parse(new XMLTokener(string), true, null, config, 0);
}
@@ -277,8 +312,32 @@ public class JSONML {
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child content and tags.
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* but just leaves it as a string.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONArray containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(XMLTokener x, JSONMLParserConfiguration config) throws JSONException {
return (JSONArray)parse(x, true, null, config, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONArray using the JsonML transform. Each XML tag is represented as
* a JSONArray in which the first element is the tag name. If the tag has
* attributes, then the second element will be JSONObject containing the
* name/value pairs. If the tag contains children, then strings and
* JSONArrays will represent the child content and tags.
* As opposed to toJSONArray this method does not attempt to convert
* any text node or attribute value to any type
* but just leaves it as a string.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener.
@@ -288,7 +347,7 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(XMLTokener x, boolean keepStrings) throws JSONException {
return (JSONArray)parse(x, true, null, keepStrings);
return (JSONArray)parse(x, true, null, keepStrings, 0);
}
@@ -305,7 +364,7 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONArray
*/
public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
return (JSONArray)parse(x, true, null, false);
return (JSONArray)parse(x, true, null, false, 0);
}
@@ -323,10 +382,10 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(String string) throws JSONException {
return (JSONObject)parse(new XMLTokener(string), false, null, false);
return (JSONObject)parse(new XMLTokener(string), false, null, false, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject using the JsonML transform. Each XML tag is represented as
@@ -343,10 +402,32 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(String string, boolean keepStrings) throws JSONException {
return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings);
return (JSONObject)parse(new XMLTokener(string), false, null, keepStrings, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject using the JsonML transform. Each XML tag is represented as
* a JSONObject with a "tagName" property. If the tag has attributes, then
* the attributes will be in the JSONObject as properties. If the tag
* contains children, the object will have a "childNodes" property which
* will be an array of strings and JsonML JSONObjects.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param string The XML source text.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(String string, JSONMLParserConfiguration config) throws JSONException {
return (JSONObject)parse(new XMLTokener(string), false, null, config, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject using the JsonML transform. Each XML tag is represented as
@@ -361,7 +442,7 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
return (JSONObject)parse(x, false, null, false);
return (JSONObject)parse(x, false, null, false, 0);
}
@@ -381,7 +462,29 @@ public class JSONML {
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(XMLTokener x, boolean keepStrings) throws JSONException {
return (JSONObject)parse(x, false, null, keepStrings);
return (JSONObject)parse(x, false, null, keepStrings, 0);
}
/**
* Convert a well-formed (but not necessarily valid) XML string into a
* JSONObject using the JsonML transform. Each XML tag is represented as
* a JSONObject with a "tagName" property. If the tag has attributes, then
* the attributes will be in the JSONObject as properties. If the tag
* contains children, the object will have a "childNodes" property which
* will be an array of strings and JsonML JSONObjects.
* Comments, prologs, DTDs, and <pre>{@code &lt;[ [ ]]>}</pre> are ignored.
* @param x An XMLTokener of the XML source text.
* @param config The parser configuration:
* JSONMLParserConfiguration.ORIGINAL is the default behaviour;
* JSONMLParserConfiguration.KEEP_STRINGS means values will not be coerced into boolean
* or numeric values and will instead be left as strings
* @return A JSONObject containing the structured data from the XML string.
* @throws JSONException Thrown on error converting to a JSONObject
*/
public static JSONObject toJSONObject(XMLTokener x, JSONMLParserConfiguration config) throws JSONException {
return (JSONObject)parse(x, false, null, config, 0);
}
@@ -462,6 +565,7 @@ public class JSONML {
return sb.toString();
}
/**
* Reverse the JSONML transformation, making an XML text from a JSONObject.
* The JSONObject must contain a "tagName" property. If it has children,

View File

@@ -0,0 +1,128 @@
package org.json;
/*
Public Domain.
*/
/**
* Configuration object for the XML to JSONML parser. The configuration is immutable.
*/
@SuppressWarnings({""})
public class JSONMLParserConfiguration {
/**
* Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML
* document to JSONML.
*/
public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1;
/**
* The default maximum nesting depth when parsing a XML document to JSONML.
*/
public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512;
/** Original Configuration of the XML to JSONML Parser. */
public static final JSONMLParserConfiguration ORIGINAL
= new JSONMLParserConfiguration();
/** Original configuration of the XML to JSONML Parser except that values are kept as strings. */
public static final JSONMLParserConfiguration KEEP_STRINGS
= new JSONMLParserConfiguration().withKeepStrings(true);
/**
* When parsing the XML into JSONML, specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*/
private boolean keepStrings;
/**
* The maximum nesting depth when parsing a XML document to JSONML.
*/
private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
/**
* Default parser configuration. Does not keep strings (tries to implicitly convert values).
*/
public JSONMLParserConfiguration() {
this.keepStrings = false;
}
/**
* Configure the parser string processing and use the default CDATA Tag Name as "content".
* @param keepStrings <code>true</code> to parse all values as string.
* <code>false</code> to try and convert XML string values into a JSON value.
* @param maxNestingDepth <code>int</code> to limit the nesting depth
*/
private JSONMLParserConfiguration(final boolean keepStrings, final int maxNestingDepth) {
this.keepStrings = keepStrings;
this.maxNestingDepth = maxNestingDepth;
}
/**
* Provides a new instance of the same configuration.
*/
@Override
protected JSONMLParserConfiguration clone() {
// future modifications to this method should always ensure a "deep"
// clone in the case of collections. i.e. if a Map is added as a configuration
// item, a new map instance should be created and if possible each value in the
// map should be cloned as well. If the values of the map are known to also
// be immutable, then a shallow clone of the map is acceptable.
return new JSONMLParserConfiguration(
this.keepStrings,
this.maxNestingDepth
);
}
/**
* When parsing the XML into JSONML, specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*
* @return The <code>keepStrings</code> configuration value.
*/
public boolean isKeepStrings() {
return this.keepStrings;
}
/**
* When parsing the XML into JSONML, specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*
* @param newVal
* new value to use for the <code>keepStrings</code> configuration option.
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public JSONMLParserConfiguration withKeepStrings(final boolean newVal) {
JSONMLParserConfiguration newConfig = this.clone();
newConfig.keepStrings = newVal;
return newConfig;
}
/**
* The maximum nesting depth that the parser will descend before throwing an exception
* when parsing the XML into JSONML.
* @return the maximum nesting depth set for this configuration
*/
public int getMaxNestingDepth() {
return maxNestingDepth;
}
/**
* Defines the maximum nesting depth that the parser will descend before throwing an exception
* when parsing the XML into JSONML. The default max nesting depth is 512, which means the parser
* will throw a JsonException if the maximum depth is reached.
* Using any negative value as a parameter is equivalent to setting no limit to the nesting depth,
* which means the parses will go as deep as the maximum call stack size allows.
* @param maxNestingDepth the maximum nesting depth allowed to the XML parser
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public JSONMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) {
JSONMLParserConfiguration newConfig = this.clone();
if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) {
newConfig.maxNestingDepth = maxNestingDepth;
} else {
newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH;
}
return newConfig;
}
}

View File

@@ -1,31 +1,10 @@
package org.json;
import java.io.Closeable;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
Public Domain.
*/
import java.io.Closeable;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
@@ -166,6 +145,10 @@ public class JSONObject {
*/
private final Map<String, Object> map;
public Class<? extends Map> getMapType() {
return map.getClass();
}
/**
* It is sometimes more convenient and less ambiguous to have a
* <code>NULL</code> object than to use Java's <code>null</code> value.
@@ -2142,6 +2125,10 @@ public class JSONObject {
if (!isNumberSimilar((Number)valueThis, (Number)valueOther)) {
return false;
}
} else if (valueThis instanceof JSONString && valueOther instanceof JSONString) {
if (!((JSONString) valueThis).toJSONString().equals(((JSONString) valueOther).toJSONString())) {
return false;
}
} else if (!valueThis.equals(valueOther)) {
return false;
}

View File

@@ -10,27 +10,7 @@ import java.util.Collections;
import java.util.List;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2018 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static java.lang.annotation.ElementType.METHOD;
@@ -31,13 +11,13 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Documented
@Retention(RUNTIME)
@Target({METHOD})
/**
* Use this annotation on a getter method to override the Bean name
* parser for Bean -&gt; JSONObject mapping. If this annotation is
* present at any level in the class hierarchy, then the method will
* not be serialized from the bean into the JSONObject.
*/
@Documented
@Retention(RUNTIME)
@Target({METHOD})
public @interface JSONPropertyIgnore { }

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2018 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static java.lang.annotation.ElementType.METHOD;
@@ -31,14 +11,14 @@ import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Documented
@Retention(RUNTIME)
@Target({METHOD})
/**
* Use this annotation on a getter method to override the Bean name
* parser for Bean -&gt; JSONObject mapping. A value set to empty string <code>""</code>
* will have the Bean parser fall back to the default field name processing.
*/
@Documented
@Retention(RUNTIME)
@Target({METHOD})
public @interface JSONPropertyName {
/**
* @return The name of the property as to be used in the JSON Object.

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2006 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.io.StringWriter;

View File

@@ -8,27 +8,7 @@ import java.io.Reader;
import java.io.StringReader;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -5,27 +5,7 @@ import java.util.Collection;
import java.util.Map;
/*
Copyright (c) 2006 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.util.Enumeration;

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2015 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.io.Reader;
@@ -118,7 +98,7 @@ public class XML {
/**
* Replace special characters with XML escapes:
*
* <pre>{@code
* <pre>{@code
* &amp; (ampersand) is replaced by &amp;amp;
* &lt; (less than) is replaced by &amp;lt;
* &gt; (greater than) is replaced by &amp;gt;
@@ -249,10 +229,14 @@ public class XML {
* The JSONObject that will include the new material.
* @param name
* The tag name.
* @param config
* The XML parser configuration.
* @param currentNestingDepth
* The current nesting depth.
* @return true if the close tag is processed.
* @throws JSONException
* @throws JSONException Thrown if any parsing error occurs.
*/
private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config)
private static boolean parse(XMLTokener x, JSONObject context, String name, XMLParserConfiguration config, int currentNestingDepth)
throws JSONException {
char c;
int i;
@@ -422,7 +406,11 @@ public class XML {
} else if (token == LT) {
// Nested element
if (parse(x, jsonObject, tagName, config)) {
if (currentNestingDepth == config.getMaxNestingDepth()) {
throw x.syntaxError("Maximum nesting depth of " + config.getMaxNestingDepth() + " reached");
}
if (parse(x, jsonObject, tagName, config, currentNestingDepth + 1)) {
if (config.getForceList().contains(tagName)) {
// Force the value to be an array
if (jsonObject.length() == 0) {
@@ -443,7 +431,7 @@ public class XML {
context.accumulate(tagName, jsonObject);
}
}
return false;
}
}
@@ -507,7 +495,7 @@ public class XML {
}
return string;
}
/**
* direct copy of {@link JSONObject#stringToNumber(String)} to maintain Android support.
*/
@@ -554,7 +542,7 @@ public class XML {
// integer representation.
// This will narrow any values to the smallest reasonable Object representation
// (Integer, Long, or BigInteger)
// BigInteger down conversion: We use a similar bitLength compare as
// BigInteger#intValueExact uses. Increases GC, but objects hold
// only what they need. i.e. Less runtime overhead if the value is
@@ -570,7 +558,7 @@ public class XML {
}
throw new NumberFormatException("val ["+val+"] is not a valid number.");
}
/**
* direct copy of {@link JSONObject#isDecimalNotation(String)} to maintain Android support.
*/
@@ -588,7 +576,7 @@ public class XML {
* 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 <pre>{@code
* "content" member. Comments, prologs, DTDs, and <pre>{@code
* &lt;[ [ ]]>}</pre>
* are ignored.
*
@@ -609,7 +597,7 @@ public class XML {
* 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 <pre>{@code
* "content" member. Comments, prologs, DTDs, and <pre>{@code
* &lt;[ [ ]]>}</pre>
* are ignored.
*
@@ -675,7 +663,7 @@ public class XML {
while (x.more()) {
x.skipPast("<");
if(x.more()) {
parse(x, jo, null, config);
parse(x, jo, null, config, 0);
}
}
return jo;
@@ -689,7 +677,7 @@ public class XML {
* 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 <pre>{@code
* "content" member. Comments, prologs, DTDs, and <pre>{@code
* &lt;[ [ ]]>}</pre>
* are ignored.
*
@@ -715,7 +703,7 @@ public class XML {
* 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 <pre>{@code
* "content" member. Comments, prologs, DTDs, and <pre>{@code
* &lt;[ [ ]]>}</pre>
* are ignored.
*
@@ -772,6 +760,28 @@ public class XML {
*/
public static String toString(final Object object, final String tagName, final XMLParserConfiguration config)
throws JSONException {
return toString(object, tagName, config, 0, 0);
}
/**
* Convert a JSONObject into a well-formed, element-normal XML string,
* either pretty print or single-lined depending on indent factor.
*
* @param object
* A JSONObject.
* @param tagName
* The optional name of the enclosing tag.
* @param config
* Configuration that can control output to XML.
* @param indentFactor
* The number of spaces to add to each level of indentation.
* @param indent
* The current ident level in spaces.
* @return
* @throws JSONException
*/
private static String toString(final Object object, final String tagName, final XMLParserConfiguration config, int indentFactor, int indent)
throws JSONException {
StringBuilder sb = new StringBuilder();
JSONArray ja;
JSONObject jo;
@@ -781,9 +791,14 @@ public class XML {
// Emit <tagName>
if (tagName != null) {
sb.append(indent(indent));
sb.append('<');
sb.append(tagName);
sb.append('>');
if(indentFactor > 0){
sb.append("\n");
indent += indentFactor;
}
}
// Loop thru the keys.
@@ -826,31 +841,39 @@ public class XML {
sb.append('<');
sb.append(key);
sb.append('>');
sb.append(toString(val, null, config));
sb.append(toString(val, null, config, indentFactor, indent));
sb.append("</");
sb.append(key);
sb.append('>');
} else {
sb.append(toString(val, key, config));
sb.append(toString(val, key, config, indentFactor, indent));
}
}
} else if ("".equals(value)) {
sb.append(indent(indent));
sb.append('<');
sb.append(key);
sb.append("/>");
if(indentFactor > 0){
sb.append("\n");
}
// Emit a new tag <k>
} else {
sb.append(toString(value, key, config));
sb.append(toString(value, key, config, indentFactor, indent));
}
}
if (tagName != null) {
// Emit the </tagName> close tag
sb.append(indent(indent - indentFactor));
sb.append("</");
sb.append(tagName);
sb.append('>');
if(indentFactor > 0){
sb.append("\n");
}
}
return sb.toString();
@@ -869,15 +892,85 @@ public class XML {
// XML does not have good support for arrays. If an array
// appears in a place where XML is lacking, synthesize an
// <array> element.
sb.append(toString(val, tagName == null ? "array" : tagName, config));
sb.append(toString(val, tagName == null ? "array" : tagName, config, indentFactor, indent));
}
return sb.toString();
}
string = (object == null) ? "null" : escape(object.toString());
return (tagName == null) ? "\"" + string + "\""
: (string.length() == 0) ? "<" + tagName + "/>" : "<" + tagName
+ ">" + string + "</" + tagName + ">";
string = (object == null) ? "null" : escape(object.toString());
if(tagName == null){
return indent(indent) + "\"" + string + "\"" + ((indentFactor > 0) ? "\n" : "");
} else if(string.length() == 0){
return indent(indent) + "<" + tagName + "/>" + ((indentFactor > 0) ? "\n" : "");
} else {
return indent(indent) + "<" + tagName
+ ">" + string + "</" + tagName + ">" + ((indentFactor > 0) ? "\n" : "");
}
}
/**
* Convert a JSONObject into a well-formed, pretty printed element-normal XML string.
*
* @param object
* A JSONObject.
* @param indentFactor
* The number of spaces to add to each level of indentation.
* @return A string.
* @throws JSONException Thrown if there is an error parsing the string
*/
public static String toString(Object object, int indentFactor){
return toString(object, null, XMLParserConfiguration.ORIGINAL, indentFactor);
}
/**
* Convert a JSONObject into a well-formed, pretty printed element-normal XML string.
*
* @param object
* A JSONObject.
* @param tagName
* The optional name of the enclosing tag.
* @param indentFactor
* The number of spaces to add to each level of indentation.
* @return A string.
* @throws JSONException Thrown if there is an error parsing the string
*/
public static String toString(final Object object, final String tagName, int indentFactor) {
return toString(object, tagName, XMLParserConfiguration.ORIGINAL, indentFactor);
}
/**
* Convert a JSONObject into a well-formed, pretty printed element-normal XML string.
*
* @param object
* A JSONObject.
* @param tagName
* The optional name of the enclosing tag.
* @param config
* Configuration that can control output to XML.
* @param indentFactor
* The number of spaces to add to each level of indentation.
* @return A string.
* @throws JSONException Thrown if there is an error parsing the string
*/
public static String toString(final Object object, final String tagName, final XMLParserConfiguration config, int indentFactor)
throws JSONException {
return toString(object, tagName, config, indentFactor, 0);
}
/**
* Return a String consisting of a number of space characters specified by indent
*
* @param indent
* The number of spaces to be appended to the String.
* @return
*/
private static final String indent(int indent) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indent; i++) {
sb.append(' ');
}
return sb.toString();
}
}

View File

@@ -1,26 +1,6 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.util.Collections;
@@ -36,6 +16,17 @@ import java.util.Set;
*/
@SuppressWarnings({""})
public class XMLParserConfiguration {
/**
* Used to indicate there's no defined limit to the maximum nesting depth when parsing a XML
* document to JSON.
*/
public static final int UNDEFINED_MAXIMUM_NESTING_DEPTH = -1;
/**
* The default maximum nesting depth when parsing a XML document to JSON.
*/
public static final int DEFAULT_MAXIMUM_NESTING_DEPTH = 512;
/** Original Configuration of the XML Parser. */
public static final XMLParserConfiguration ORIGINAL
= new XMLParserConfiguration();
@@ -48,14 +39,14 @@ public class XMLParserConfiguration {
* they should try to be guessed into JSON values (numeric, boolean, string)
*/
private boolean keepStrings;
/**
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
* processing.
*/
private String cDataTagName;
/**
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(<code>false</code>), or they should be converted to
@@ -74,6 +65,11 @@ public class XMLParserConfiguration {
*/
private Set<String> forceList;
/**
* The maximum nesting depth when parsing a XML document to JSON.
*/
private int maxNestingDepth = DEFAULT_MAXIMUM_NESTING_DEPTH;
/**
* Default parser configuration. Does not keep strings (tries to implicitly convert
* values), and the CDATA Tag Name is "content".
@@ -160,15 +156,18 @@ public class XMLParserConfiguration {
* <code>false</code> to parse values with attribute xsi:nil="true" as {"xsi:nil":true}.
* @param xsiTypeMap <code>new HashMap<String, XMLXsiTypeConverter<?>>()</code> to parse values with attribute
* xsi:type="integer" as integer, xsi:type="string" as string
* @param forceList <code>new HashSet<String>()</code> to parse the provided tags' values as arrays
* @param forceList <code>new HashSet<String>()</code> to parse the provided tags' values as arrays
* @param maxNestingDepth <code>int</code> to limit the nesting depth
*/
private XMLParserConfiguration (final boolean keepStrings, final String cDataTagName,
final boolean convertNilAttributeToNull, final Map<String, XMLXsiTypeConverter<?>> xsiTypeMap, final Set<String> forceList ) {
final boolean convertNilAttributeToNull, final Map<String, XMLXsiTypeConverter<?>> xsiTypeMap, final Set<String> forceList,
final int maxNestingDepth) {
this.keepStrings = keepStrings;
this.cDataTagName = cDataTagName;
this.convertNilAttributeToNull = convertNilAttributeToNull;
this.xsiTypeMap = Collections.unmodifiableMap(xsiTypeMap);
this.forceList = Collections.unmodifiableSet(forceList);
this.maxNestingDepth = maxNestingDepth;
}
/**
@@ -186,14 +185,15 @@ public class XMLParserConfiguration {
this.cDataTagName,
this.convertNilAttributeToNull,
this.xsiTypeMap,
this.forceList
this.forceList,
this.maxNestingDepth
);
}
/**
* When parsing the XML into JSON, specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*
*
* @return The <code>keepStrings</code> configuration value.
*/
public boolean isKeepStrings() {
@@ -203,10 +203,10 @@ public class XMLParserConfiguration {
/**
* When parsing the XML into JSON, specifies if values should be kept as strings (<code>true</code>), or if
* they should try to be guessed into JSON values (numeric, boolean, string)
*
*
* @param newVal
* new value to use for the <code>keepStrings</code> configuration option.
*
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withKeepStrings(final boolean newVal) {
@@ -219,7 +219,7 @@ public class XMLParserConfiguration {
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
* processing.
*
*
* @return The <code>cDataTagName</code> configuration value.
*/
public String getcDataTagName() {
@@ -230,10 +230,10 @@ public class XMLParserConfiguration {
* The name of the key in a JSON Object that indicates a CDATA section. Historically this has
* been the value "content" but can be changed. Use <code>null</code> to indicate no CDATA
* processing.
*
*
* @param newVal
* new value to use for the <code>cDataTagName</code> configuration option.
*
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withcDataTagName(final String newVal) {
@@ -246,7 +246,7 @@ public class XMLParserConfiguration {
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(<code>false</code>), or they should be converted to
* <code>null</code>(<code>true</code>)
*
*
* @return The <code>convertNilAttributeToNull</code> configuration value.
*/
public boolean isConvertNilAttributeToNull() {
@@ -257,10 +257,10 @@ public class XMLParserConfiguration {
* When parsing the XML into JSON, specifies if values with attribute xsi:nil="true"
* should be kept as attribute(<code>false</code>), or they should be converted to
* <code>null</code>(<code>true</code>)
*
*
* @param newVal
* new value to use for the <code>convertNilAttributeToNull</code> configuration option.
*
*
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withConvertNilAttributeToNull(final boolean newVal) {
@@ -298,7 +298,7 @@ public class XMLParserConfiguration {
/**
* When parsing the XML into JSON, specifies that tags that will be converted to arrays
* in this configuration {@code Set<String>} to parse the provided tags' values as arrays
* in this configuration {@code Set<String>} to parse the provided tags' values as arrays
* @return <code>forceList</code> unmodifiable configuration set.
*/
public Set<String> getForceList() {
@@ -307,8 +307,8 @@ public class XMLParserConfiguration {
/**
* When parsing the XML into JSON, specifies that tags that will be converted to arrays
* in this configuration {@code Set<String>} to parse the provided tags' values as arrays
* @param forceList {@code new HashSet<String>()} to parse the provided tags' values as arrays
* in this configuration {@code Set<String>} to parse the provided tags' values as arrays
* @param forceList {@code new HashSet<String>()} to parse the provided tags' values as arrays
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withForceList(final Set<String> forceList) {
@@ -317,4 +317,34 @@ public class XMLParserConfiguration {
newConfig.forceList = Collections.unmodifiableSet(cloneForceList);
return newConfig;
}
/**
* The maximum nesting depth that the parser will descend before throwing an exception
* when parsing the XML into JSON.
* @return the maximum nesting depth set for this configuration
*/
public int getMaxNestingDepth() {
return maxNestingDepth;
}
/**
* Defines the maximum nesting depth that the parser will descend before throwing an exception
* when parsing the XML into JSON. The default max nesting depth is 512, which means the parser
* will throw a JsonException if the maximum depth is reached.
* Using any negative value as a parameter is equivalent to setting no limit to the nesting depth,
* which means the parses will go as deep as the maximum call stack size allows.
* @param maxNestingDepth the maximum nesting depth allowed to the XML parser
* @return The existing configuration will not be modified. A new configuration is returned.
*/
public XMLParserConfiguration withMaxNestingDepth(int maxNestingDepth) {
XMLParserConfiguration newConfig = this.clone();
if (maxNestingDepth > UNDEFINED_MAXIMUM_NESTING_DEPTH) {
newConfig.maxNestingDepth = maxNestingDepth;
} else {
newConfig.maxNestingDepth = UNDEFINED_MAXIMUM_NESTING_DEPTH;
}
return newConfig;
}
}

View File

@@ -1,27 +1,7 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.io.Reader;

View File

@@ -1,26 +1,6 @@
package org.json;
/*
Copyright (c) 2002 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
/**

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.assertEquals;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -49,7 +29,9 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONPointerException;
import org.json.JSONString;
import org.json.JSONTokener;
import org.json.junit.data.MyJsonString;
import org.junit.Test;
import com.jayway.jsonpath.Configuration;
@@ -237,6 +219,10 @@ public class JSONArrayTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaObj));
Util.checkJSONArrayMaps(expected);
Util.checkJSONArrayMaps(jaObj);
Util.checkJSONArrayMaps(jaRaw);
Util.checkJSONArrayMaps(jaInt);
}
/**
@@ -275,6 +261,7 @@ public class JSONArrayTest {
myList.get(i),
jsonArray.getString(myInts.length + i));
}
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -308,6 +295,9 @@ public class JSONArrayTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaInt));
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
jaRaw, jaObj, jaInt
)));
}
@@ -351,6 +341,9 @@ public class JSONArrayTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaObjObj));
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
expected, jaRaw, jaStrObj, jaStrInt, jaObjObj
)));
}
/**
@@ -397,6 +390,7 @@ public class JSONArrayTest {
new Long(-1).equals(jsonArray.getLong(12)));
assertTrue("Array value null", jsonArray.isNull(-1));
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -463,6 +457,7 @@ public class JSONArrayTest {
assertEquals("Expected an exception message",
"JSONArray[5] is not a String (class java.math.BigDecimal : 0.002345).",e.getMessage());
}
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -499,6 +494,7 @@ public class JSONArrayTest {
assertTrue("expected value4", "value4".equals(jsonArray.query("/10/key4")));
assertTrue("expected 0", Integer.valueOf(0).equals(jsonArray.query("/11")));
assertTrue("expected \"-1\"", "-1".equals(jsonArray.query("/12")));
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -512,6 +508,9 @@ public class JSONArrayTest {
assertTrue("expected JSONArray length 13. instead found "+jsonArray.length(), jsonArray.length() == 13);
JSONArray nestedJsonArray = jsonArray.getJSONArray(9);
assertTrue("expected JSONArray length 1", nestedJsonArray.length() == 1);
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
jsonArray, nestedJsonArray
)));
}
/**
@@ -587,6 +586,10 @@ public class JSONArrayTest {
"hello".equals(jsonArray.optString(4)));
assertTrue("Array opt string default implicit",
"".equals(jsonArray.optString(-1)));
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
jsonArray, nestedJsonArray
)));
Util.checkJSONObjectMaps(nestedJsonObject);
}
/**
@@ -601,7 +604,9 @@ public class JSONArrayTest {
assertTrue("unexpected optLong value",ja.optLong(0,0)==123);
assertTrue("unexpected optDouble value",ja.optDouble(0,0.0)==123.0);
assertTrue("unexpected optBigInteger value",ja.optBigInteger(0,BigInteger.ZERO).compareTo(new BigInteger("123"))==0);
assertTrue("unexpected optBigDecimal value",ja.optBigDecimal(0,BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0); }
assertTrue("unexpected optBigDecimal value",ja.optBigDecimal(0,BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0);
Util.checkJSONArrayMaps(ja);
}
/**
* Exercise the JSONArray.put(value) method with various parameters
@@ -677,6 +682,8 @@ public class JSONArrayTest {
assertTrue("expected 2 items in [9]", ((List<?>)(JsonPath.read(doc, "$[9]"))).size() == 2);
assertTrue("expected 1", Integer.valueOf(1).equals(jsonArray.query("/9/0")));
assertTrue("expected 2", Integer.valueOf(2).equals(jsonArray.query("/9/1")));
Util.checkJSONArrayMaps(jsonArray);
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -756,6 +763,8 @@ public class JSONArrayTest {
assertTrue("expected 2", Integer.valueOf(2).equals(jsonArray.query("/9/1")));
assertTrue("expected 1 item in [10]", ((Map<?,?>)(JsonPath.read(doc, "$[10]"))).size() == 1);
assertTrue("expected v1", "v1".equals(jsonArray.query("/10/k1")));
Util.checkJSONObjectMaps(jsonObject);
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -772,6 +781,7 @@ public class JSONArrayTest {
jsonArray.remove(0);
assertTrue("array should be empty", null == jsonArray.remove(5));
assertTrue("jsonArray should be empty", jsonArray.isEmpty());
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -811,6 +821,12 @@ public class JSONArrayTest {
otherJsonArray.put("world");
assertTrue("arrays values differ",
!jsonArray.similar(otherJsonArray));
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
jsonArray, otherJsonArray
)));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObject, otherJsonObject
)));
}
/**
@@ -894,6 +910,7 @@ public class JSONArrayTest {
for (String s : jsonArray4Strs) {
list.contains(s);
}
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -905,6 +922,9 @@ public class JSONArrayTest {
JSONArray jsonArray = new JSONArray();
assertTrue("toJSONObject should return null",
null == jsonArray.toJSONObject(names));
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
names, jsonArray
)));
}
/**
@@ -926,6 +946,7 @@ public class JSONArrayTest {
assertTrue("expected 5", Integer.valueOf(5).equals(jsonArray.query("/4")));
assertTrue("expected 6", Integer.valueOf(6).equals(jsonArray.query("/5")));
assertTrue("expected 7", Integer.valueOf(7).equals(jsonArray.query("/6")));
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -968,6 +989,10 @@ public class JSONArrayTest {
assertTrue("Array value string long",
new Long(-1).equals(Long.parseLong((String) it.next())));
assertTrue("should be at end of array", !it.hasNext());
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
jsonArray, nestedJsonArray
)));
Util.checkJSONObjectMaps(nestedJsonObject);
}
@Test(expected = JSONPointerException.class)
@@ -1010,6 +1035,7 @@ public class JSONArrayTest {
} finally {
stringWriter.close();
}
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -1069,9 +1095,11 @@ public class JSONArrayTest {
&& actualStr.contains("\"key2\": false")
&& actualStr.contains("\"key3\": 3.14")
);
Util.checkJSONArrayMaps(finalArray);
} finally {
stringWriter.close();
}
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -1182,6 +1210,7 @@ public class JSONArrayTest {
// assert that the new list is mutable
assertTrue("Removing an entry should succeed", list.remove(2) != null);
assertTrue("List should have 2 elements", list.size() == 2);
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -1190,13 +1219,13 @@ public class JSONArrayTest {
*/
@Test
public void testJSONArrayInt() {
assertNotNull(new JSONArray(0));
assertNotNull(new JSONArray(5));
// Check Size -> Even though the capacity of the JSONArray can be specified using a positive
// integer but the length of JSONArray always reflects upon the items added into it.
assertEquals(0l, new JSONArray(10).length());
assertNotNull(new JSONArray(0));
assertNotNull(new JSONArray(5));
// Check Size -> Even though the capacity of the JSONArray can be specified using a positive
// integer but the length of JSONArray always reflects upon the items added into it.
// assertEquals(0l, new JSONArray(10).length());
try {
assertNotNull("Should throw an exception", new JSONArray(-1));
assertNotNull("Should throw an exception", new JSONArray(-1));
} catch (JSONException e) {
assertEquals("Expected an exception message",
"JSONArray initial capacity cannot be negative.",
@@ -1223,8 +1252,8 @@ public class JSONArrayTest {
((Collection<Object>)o).add("test");
((Collection<Object>)o).add(false);
try {
a = new JSONArray(o);
assertNull("Should error", a);
JSONArray a0 = new JSONArray(o);
assertNull("Should error", a0);
} catch (JSONException ex) {
}
@@ -1232,10 +1261,11 @@ public class JSONArrayTest {
// this is required for backwards compatibility
o = a;
try {
a = new JSONArray(o);
assertNull("Should error", a);
JSONArray a1 = new JSONArray(o);
assertNull("Should error", a1);
} catch (JSONException ex) {
}
Util.checkJSONArrayMaps(a);
}
/**
@@ -1252,6 +1282,9 @@ public class JSONArrayTest {
for(int i = 0; i < a1.length(); i++) {
assertEquals("index " + i + " are equal", a1.get(i), a2.get(i));
}
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
a1, a2
)));
}
/**
@@ -1269,6 +1302,9 @@ public class JSONArrayTest {
for(int i = 0; i < a1.length(); i++) {
assertEquals("index " + i + " are equal", a1.get(i), a2.get(i));
}
Util.checkJSONArraysMaps(new ArrayList<JSONArray>(Arrays.asList(
a1, a2
)));
}
/**
@@ -1284,6 +1320,7 @@ public class JSONArrayTest {
jsonArray.clear(); //Clears the JSONArray
assertTrue("expected jsonArray.length() == 0", jsonArray.length() == 0); //Check if its length is 0
jsonArray.getInt(0); //Should throws org.json.JSONException: JSONArray[0] not found
Util.checkJSONArrayMaps(jsonArray);
}
/**
@@ -1297,5 +1334,27 @@ public class JSONArrayTest {
JSONArray json_input = new JSONArray(tokener);
assertNotNull(json_input);
fail("Excepected Exception.");
Util.checkJSONArrayMaps(json_input);
}
@Test
public void testIssue682SimilarityOfJSONString() {
JSONArray ja1 = new JSONArray()
.put(new MyJsonString())
.put(2);
JSONArray ja2 = new JSONArray()
.put(new MyJsonString())
.put(2);
assertTrue(ja1.similar(ja2));
JSONArray ja3 = new JSONArray()
.put(new JSONString() {
@Override
public String toJSONString() {
return "\"different value\"";
}
})
.put(2);
assertFalse(ja1.similar(ja3));
}
}

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;
@@ -31,19 +11,19 @@ import org.junit.Test;
/**
* Tests for org.json.JSONML.java
*
*
* Certain inputs are expected to result in exceptions. These tests are
* executed first. JSONML provides an API to:
* Convert an XML string into a JSONArray or a JSONObject.
* Convert an XML string into a JSONArray or a JSONObject.
* Convert a JSONArray or JSONObject into an XML string.
* Both fromstring and tostring operations operations should be symmetrical
* within the limits of JSONML.
* within the limits of JSONML.
* It should be possible to perform the following operations, which should
* result in the original string being recovered, within the limits of the
* underlying classes:
* Convert a string -> JSONArray -> string -> JSONObject -> string
* Convert a string -> JSONObject -> string -> JSONArray -> string
*
*
*/
public class JSONMLTest {
@@ -76,7 +56,7 @@ public class JSONMLTest {
/**
* Attempts to call JSONML.toString() with a null JSONArray.
* Expects a NullPointerException.
* Expects a NullPointerException.
*/
@Test(expected=NullPointerException.class)
public void nullJSONXMLException() {
@@ -89,7 +69,7 @@ public class JSONMLTest {
/**
* Attempts to call JSONML.toString() with a null JSONArray.
* Expects a JSONException.
* Expects a JSONException.
*/
@Test
public void emptyJSONXMLException() {
@@ -145,7 +125,7 @@ public class JSONMLTest {
"[\"addresses\","+
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
// this array has no name
// this array has no name
"["+
"[\"name\"],"+
"[\"nocontent\"],"+
@@ -200,7 +180,7 @@ public class JSONMLTest {
}
/**
* Attempts to transform a malformed XML document
* Attempts to transform a malformed XML document
* (element tag has a frontslash) to a JSONArray.\
* Expects a JSONException
*/
@@ -211,7 +191,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because the 'name' element
* contains an invalid frontslash.
*/
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
@@ -236,7 +216,7 @@ public class JSONMLTest {
*/
@Test
public void invalidBangInTagException() {
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
@@ -266,7 +246,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because an element
* starts with '!' and has no closing tag
*/
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
@@ -296,7 +276,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because an element
* has no closing '>'.
*/
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
@@ -326,7 +306,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because an element
* has no name after the closing tag '</'.
*/
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
@@ -356,7 +336,7 @@ public class JSONMLTest {
* In this case, the XML is invalid because an element
* has '>' after the closing tag '</' and name.
*/
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation=\"test.xsd\">\n"+
@@ -384,9 +364,9 @@ public class JSONMLTest {
/**
* xmlStr contains XML text which is transformed into a JSONArray.
* In this case, the XML is invalid because an element
* does not have a complete CDATA string.
* does not have a complete CDATA string.
*/
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
" xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
@@ -408,7 +388,7 @@ public class JSONMLTest {
/**
* Convert an XML document into a JSONArray, then use JSONML.toString()
* to convert it into a string. This string is then converted back into
* a JSONArray. Both JSONArrays are compared against a control to
* a JSONArray. Both JSONArrays are compared against a control to
* confirm the contents.
*/
@Test
@@ -425,7 +405,7 @@ public class JSONMLTest {
* which is used to create a final JSONArray, which is also compared
* against the expected JSONArray.
*/
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
"xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
@@ -434,7 +414,7 @@ public class JSONMLTest {
"<nocontent/>>\n"+
"</address>\n"+
"</addresses>";
String expectedStr =
String expectedStr =
"[\"addresses\","+
"{\"xsi:noNamespaceSchemaLocation\":\"test.xsd\","+
"\"xmlns:xsi\":\"http://www.w3.org/2001/XMLSchema-instance\"},"+
@@ -454,12 +434,12 @@ public class JSONMLTest {
}
/**
* Convert an XML document into a JSONObject. Use JSONML.toString() to
* Convert an XML document into a JSONObject. Use JSONML.toString() to
* convert it back into a string, and then re-convert it into a JSONObject.
* Both JSONObjects are compared against a control JSONObject to confirm
* the contents.
* <p>
* Next convert the XML document into a JSONArray. Use JSONML.toString() to
* Next convert the XML document into a JSONArray. Use JSONML.toString() to
* convert it back into a string, and then re-convert it into a JSONArray.
* Both JSONArrays are compared against a control JSONArray to confirm
* the contents.
@@ -472,23 +452,23 @@ public class JSONMLTest {
/**
* xmlStr contains XML text which is transformed into a JSONObject,
* restored to XML, transformed into a JSONArray, and then restored
* to XML again. Both JSONObject and JSONArray should contain the same
* to XML again. Both JSONObject and JSONArray should contain the same
* information and should produce the same XML, allowing for non-ordered
* attributes.
*
*
* Transformation to JSONObject:
* The elementName is stored as a string where key="tagName"
* Attributes are simply stored as key/value pairs
* If the element has either content or child elements, they are stored
* in a jsonArray with key="childNodes".
*
*
* Transformation to JSONArray:
* 1st entry = elementname
* 2nd entry = attributes object (if present)
* 3rd entry = content (if present)
* 4th entry = child element JSONArrays (if present)
*/
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<addresses xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""+
"xsi:noNamespaceSchemaLocation='test.xsd'>\n"+
@@ -605,7 +585,7 @@ public class JSONMLTest {
"\"tagName\":\"addresses\""+
"}";
String expectedJSONArrayStr =
String expectedJSONArrayStr =
"["+
"\"addresses\","+
"{"+
@@ -665,12 +645,12 @@ public class JSONMLTest {
JSONObject finalJsonObject = JSONML.toJSONObject(jsonObjectXmlToStr);
Util.compareActualVsExpectedJsonObjects(finalJsonObject, expectedJsonObject);
// create a JSON array from the original string and make sure it
// create a JSON array from the original string and make sure it
// looks as expected
JSONArray jsonArray = JSONML.toJSONArray(xmlStr);
JSONArray expectedJsonArray = new JSONArray(expectedJSONArrayStr);
Util.compareActualVsExpectedJsonArrays(jsonArray,expectedJsonArray);
// restore the XML, then make another JSONArray and make sure it
// looks as expected
String jsonArrayXmlToStr = JSONML.toString(jsonArray);
@@ -688,14 +668,14 @@ public class JSONMLTest {
* Convert an XML document which contains embedded comments into
* a JSONArray. Use JSONML.toString() to turn it into a string, then
* reconvert it into a JSONArray. Compare both JSONArrays to a control
* JSONArray to confirm the contents.
* JSONArray to confirm the contents.
* <p>
* This test shows how XML comments are handled.
*/
@Test
public void commentsInXML() {
String xmlStr =
String xmlStr =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+
"<!-- this is a comment -->\n"+
"<addresses>\n"+
@@ -754,7 +734,7 @@ public class JSONMLTest {
final String expectedJsonString = "[\"root\",[\"id\",\"01\"],[\"id\",\"1\"],[\"id\",\"00\"],[\"id\",\"0\"],[\"item\",{\"id\":\"01\"}],[\"title\",\"True\"]]";
final JSONArray json = JSONML.toJSONArray(originalXml,true);
assertEquals(expectedJsonString, json.toString());
final String reverseXml = JSONML.toString(json);
assertEquals(originalXml, reverseXml);
}
@@ -769,7 +749,7 @@ public class JSONMLTest {
final String revertedXml = JSONML.toString(jsonArray);
assertEquals(revertedXml, originalXml);
}
/**
* JSON string cannot be reverted to original xml. See test result in
* comment below.
@@ -790,7 +770,7 @@ public class JSONMLTest {
// 1. Our XML parser does not handle generic HTML entities, only valid XML entities. Hence &nbsp;
// or other HTML specific entities would fail on reversability
// 2. Our JSON implementation for storing the XML attributes uses the standard unordered map.
// This means that <tag attr1="v1" attr2="v2" /> can not be reversed reliably.
// This means that <tag attr1="v1" attr2="v2" /> can not be reversed reliably.
//
// /**
// * Test texts taken from jsonml.org. Currently our implementation FAILS this conversion but shouldn't.
@@ -803,13 +783,13 @@ public class JSONMLTest {
// final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"\u00A0\",[\"span\",{ \"style\" : \"background-color:maroon\" },\"\u00A9\"],\"\u00A0\"]]]";
// final JSONArray json = JSONML.toJSONArray(originalXml,true);
// final String actualJsonString = json.toString();
//
//
// final String reverseXml = JSONML.toString(json);
// assertNotEquals(originalXml, reverseXml);
//
// assertNotEquals(expectedJsonString, actualJsonString);
// }
//
//
// /**
// * Test texts taken from jsonml.org but modified to have XML entities only.
// */
@@ -819,15 +799,15 @@ public class JSONMLTest {
// final String expectedJsonString = "[\"table\",{\"class\" : \"MyTable\",\"style\" : \"background-color:yellow\"},[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#550758\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:red\"},\"Example text here\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#993101\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:green\"},\"127624015\"]],[\"tr\",[\"td\",{\"class\" : \"MyTD\",\"style\" : \"border:1px solid black\"},\"#E33D87\"],[\"td\",{\"class\" : \"MyTD\",\"style\" : \"background-color:blue\"},\"&\",[\"span\",{ \"style\" : \"background-color:maroon\" },\">\"],\"<\"]]]";
// final JSONArray jsonML = JSONML.toJSONArray(originalXml,true);
// final String actualJsonString = jsonML.toString();
//
//
// final String reverseXml = JSONML.toString(jsonML);
// // currently not equal because the hashing of the attribute objects makes the attribute
// // order not happen the same way twice
// // order not happen the same way twice
// assertEquals(originalXml, reverseXml);
//
// assertEquals(expectedJsonString, actualJsonString);
// }
@Test (timeout = 6000)
public void testIssue484InfinteLoop1() {
try {
@@ -839,11 +819,11 @@ public class JSONMLTest {
ex.getMessage());
}
}
@Test (timeout = 6000)
public void testIssue484InfinteLoop2() {
try {
String input = "??*\n" +
String input = "??*\n" +
"??|?CglR??`??>?w??PIlr??D?$?-?o??O?*??{OD?Y??`2a????NM?bq?:O?>S$ ?J?B.gUK?m\b??zE???!v]???????c??????h???s???g???`?qbi??:Zl?)?}1^??k?0??:$V?$?Ovs(}J??????2;gQ????Tg?K?`?h%c?hmGA?<!C*?9?~?t?)??,zA???S}?Q??.q?j????]";
JSONML.toJSONObject(input);
fail("Exception expected for invalid JSON.");
@@ -853,4 +833,128 @@ public class JSONMLTest {
ex.getMessage());
}
}
@Test
public void testToJSONArrayMaxNestingDepthOf42IsRespected() {
final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "<a>");
final int maxNestingDepth = 42;
try {
JSONML.toJSONArray(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testToJSONArrayMaxNestingDepthIsRespectedWithValidXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 1;
try {
JSONML.toJSONArray(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testToJSONArrayMaxNestingDepthWithValidFittingXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 3;
try {
JSONML.toJSONArray(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
} catch (JSONException e) {
e.printStackTrace();
fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " +
"parameter of the JSONMLParserConfiguration used");
}
}
@Test
public void testToJSONObjectMaxNestingDepthOf42IsRespected() {
final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "<a>");
final int maxNestingDepth = 42;
try {
JSONML.toJSONObject(wayTooLongMalformedXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testToJSONObjectMaxNestingDepthIsRespectedWithValidXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 1;
try {
JSONML.toJSONObject(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testToJSONObjectMaxNestingDepthWithValidFittingXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 3;
try {
JSONML.toJSONObject(perfectlyFineXML, JSONMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
} catch (JSONException e) {
e.printStackTrace();
fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " +
"parameter of the JSONMLParserConfiguration used");
}
}
}

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;

View File

@@ -0,0 +1,126 @@
package org.json.junit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(value = Parameterized.class)
public class JSONObjectNumberTest {
private final String objectString;
private Integer value = 50;
@Parameters(name = "{index}: {0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{"{value:50}", 1},
{"{value:50.0}", 1},
{"{value:5e1}", 1},
{"{value:5E1}", 1},
{"{value:5e1}", 1},
{"{value:'50'}", 1},
{"{value:-50}", -1},
{"{value:-50.0}", -1},
{"{value:-5e1}", -1},
{"{value:-5E1}", -1},
{"{value:-5e1}", -1},
{"{value:'-50'}", -1}
// JSON does not support octal or hex numbers;
// see https://stackoverflow.com/a/52671839/6323312
// "{value:062}", // octal 50
// "{value:0x32}" // hex 50
});
}
public JSONObjectNumberTest(String objectString, int resultIsNegative) {
this.objectString = objectString;
this.value *= resultIsNegative;
}
private JSONObject object;
@Before
public void setJsonObject() {
object = new JSONObject(objectString);
}
@Test
public void testGetNumber() {
assertEquals(value.intValue(), object.getNumber("value").intValue());
}
@Test
public void testGetBigDecimal() {
assertTrue(BigDecimal.valueOf(value).compareTo(object.getBigDecimal("value")) == 0);
}
@Test
public void testGetBigInteger() {
assertEquals(BigInteger.valueOf(value), object.getBigInteger("value"));
}
@Test
public void testGetFloat() {
assertEquals(value.floatValue(), object.getFloat("value"), 0.0f);
}
@Test
public void testGetDouble() {
assertEquals(value.doubleValue(), object.getDouble("value"), 0.0d);
}
@Test
public void testGetInt() {
assertEquals(value.intValue(), object.getInt("value"));
}
@Test
public void testGetLong() {
assertEquals(value.longValue(), object.getLong("value"));
}
@Test
public void testOptNumber() {
assertEquals(value.intValue(), object.optNumber("value").intValue());
}
@Test
public void testOptBigDecimal() {
assertTrue(BigDecimal.valueOf(value).compareTo(object.optBigDecimal("value", null)) == 0);
}
@Test
public void testOptBigInteger() {
assertEquals(BigInteger.valueOf(value), object.optBigInteger("value", null));
}
@Test
public void testOptFloat() {
assertEquals(value.floatValue(), object.optFloat("value"), 0.0f);
}
@Test
public void testOptDouble() {
assertEquals(value.doubleValue(), object.optDouble("value"), 0.0d);
}
@Test
public void testOptInt() {
assertEquals(value.intValue(), object.optInt("value"));
}
@Test
public void testOptLong() {
assertEquals(value.longValue(), object.optLong("value"));
}
}

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -41,14 +21,7 @@ import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
@@ -57,6 +30,7 @@ import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONPointerException;
import org.json.JSONString;
import org.json.JSONTokener;
import org.json.XML;
import org.json.junit.data.BrokenToString;
@@ -80,6 +54,7 @@ import org.json.junit.data.Singleton;
import org.json.junit.data.SingletonEnum;
import org.json.junit.data.WeirdList;
import org.junit.Test;
import org.json.junit.Util;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
@@ -140,8 +115,12 @@ public class JSONObjectTest {
JSONObject first = new JSONObject("{\"a\": 1, \"b\": 2, \"c\": 3}");
JSONObject second = new JSONObject("{\"a\": 1, \"b\": 2.0, \"c\": 4}");
assertFalse("first-second should eval to false", first.similar(second));
List<JSONObject> jsonObjects = new ArrayList<JSONObject>(
Arrays.asList(obj1, obj2, obj3, obj4, obj5)
);
Util.checkJSONObjectsMaps(jsonObjects);
}
@Test
public void timeNumberParsing() {
// test data to use
@@ -214,7 +193,9 @@ public class JSONObjectTest {
*/
@Test(expected=NullPointerException.class)
public void jsonObjectByNullBean() {
assertNull("Expected an exception",new JSONObject((MyBean)null));
JSONObject jsonObject = new JSONObject((MyBean)null);
assertNull("Expected an exception", jsonObject);
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -232,6 +213,7 @@ public class JSONObjectTest {
assertTrue("expected value1", textStr.contains("\"value1\""));
assertTrue("expected key2", textStr.contains("\"key2\""));
assertTrue("expected 42", textStr.contains("42"));
Util.checkJSONObjectMaps(jsonObject);
}
@Test
@@ -252,6 +234,7 @@ public class JSONObjectTest {
final String actualString = json.optString("key");
assert str.equals(actualString) : "Incorrect key value. Got "
+ actualString + " expected " + str;
Util.checkJSONObjectMaps(json);
}
/**
@@ -261,6 +244,7 @@ public class JSONObjectTest {
public void emptyJsonObject() {
JSONObject jsonObject = new JSONObject();
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -291,6 +275,7 @@ public class JSONObjectTest {
assertTrue("expected \"nullKey\":null", JSONObject.NULL.equals(jsonObjectByName.query("/nullKey")));
assertTrue("expected \"stringKey\":\"hello world!\"", "hello world!".equals(jsonObjectByName.query("/stringKey")));
assertTrue("expected \"doubleKey\":-23.45e67", new BigDecimal("-23.45e67").equals(jsonObjectByName.query("/doubleKey")));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(jsonObject, jsonObjectByName)));
}
/**
@@ -304,6 +289,7 @@ public class JSONObjectTest {
Map<String, Object> map = null;
JSONObject jsonObject = new JSONObject(map);
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -329,6 +315,7 @@ public class JSONObjectTest {
assertTrue("expected \"stringKey\":\"hello world!\"", "hello world!".equals(jsonObject.query("/stringKey")));
assertTrue("expected \"escapeStringKey\":\"h\be\tllo w\u1234orld!\"", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/escapeStringKey")));
assertTrue("expected \"doubleKey\":-23.45e67", Double.valueOf("-23.45e67").equals(jsonObject.query("/doubleKey")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -367,6 +354,9 @@ public class JSONObjectTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaObjObj));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(
Arrays.asList(jaRaw, jaStrObj, jaStrInt, jaObjObj))
);
}
/**
@@ -384,8 +374,8 @@ public class JSONObjectTest {
* The only getter is getNumber (key=number), whose return value is
* BigDecimal(42).
*/
JSONObject jsonObject = new JSONObject(new MyNumberContainer());
String actual = jsonObject.toString();
JSONObject jsonObject0 = new JSONObject(new MyNumberContainer());
String actual = jsonObject0.toString();
String expected = "{\"myNumber\":{\"number\":42}}";
assertEquals("Equal", expected , actual);
@@ -397,9 +387,9 @@ public class JSONObjectTest {
* The MyNumber.toString() method is responsible for
* returning a reasonable value: the string '42'.
*/
jsonObject = new JSONObject();
jsonObject.put("myNumber", new MyNumber());
actual = jsonObject.toString();
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("myNumber", new MyNumber());
actual = jsonObject1.toString();
expected = "{\"myNumber\":42}";
assertEquals("Equal", expected , actual);
@@ -411,8 +401,8 @@ public class JSONObjectTest {
* wrap() inserts the value as a string. That is why 42 comes back
* wrapped in quotes.
*/
jsonObject = new JSONObject(Collections.singletonMap("myNumber", new AtomicInteger(42)));
actual = jsonObject.toString();
JSONObject jsonObject2 = new JSONObject(Collections.singletonMap("myNumber", new AtomicInteger(42)));
actual = jsonObject2.toString();
expected = "{\"myNumber\":\"42\"}";
assertEquals("Equal", expected , actual);
@@ -422,9 +412,9 @@ public class JSONObjectTest {
* AtomicInteger is recognized as a Number, and converted via
* numberToString() into the unquoted string '42'.
*/
jsonObject = new JSONObject();
jsonObject.put("myNumber", new AtomicInteger(42));
actual = jsonObject.toString();
JSONObject jsonObject3 = new JSONObject();
jsonObject3.put("myNumber", new AtomicInteger(42));
actual = jsonObject3.toString();
expected = "{\"myNumber\":42}";
assertEquals("Equal", expected , actual);
@@ -435,11 +425,11 @@ public class JSONObjectTest {
* bean and inserted into a contained JSONObject. It has 2 getters,
* for numerator and denominator.
*/
jsonObject = new JSONObject(Collections.singletonMap("myNumber", new Fraction(4,2)));
assertEquals(1, jsonObject.length());
assertEquals(2, ((JSONObject)(jsonObject.get("myNumber"))).length());
assertEquals("Numerator", BigInteger.valueOf(4) , jsonObject.query("/myNumber/numerator"));
assertEquals("Denominator", BigInteger.valueOf(2) , jsonObject.query("/myNumber/denominator"));
JSONObject jsonObject4 = new JSONObject(Collections.singletonMap("myNumber", new Fraction(4,2)));
assertEquals(1, jsonObject4.length());
assertEquals(2, ((JSONObject)(jsonObject4.get("myNumber"))).length());
assertEquals("Numerator", BigInteger.valueOf(4) , jsonObject4.query("/myNumber/numerator"));
assertEquals("Denominator", BigInteger.valueOf(2) , jsonObject4.query("/myNumber/denominator"));
/**
* JSONObject.put() inserts the Fraction directly into the
@@ -449,11 +439,15 @@ public class JSONObjectTest {
* BigDecimal sanity check fails, so writeValue() defaults
* to returning a safe JSON quoted string. Pretty slick!
*/
jsonObject = new JSONObject();
jsonObject.put("myNumber", new Fraction(4,2));
actual = jsonObject.toString();
JSONObject jsonObject5 = new JSONObject();
jsonObject5.put("myNumber", new Fraction(4,2));
actual = jsonObject5.toString();
expected = "{\"myNumber\":\"4/2\"}"; // valid JSON, bug fixed
assertEquals("Equal", expected , actual);
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObject0, jsonObject1, jsonObject2, jsonObject3, jsonObject4, jsonObject5
)));
}
/**
@@ -488,6 +482,10 @@ public class JSONObjectTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaInt));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jaRaw, jaObj, jaInt
)));
}
@@ -531,6 +529,10 @@ public class JSONObjectTest {
assertTrue(
"The RAW Collection should give me the same as the Typed Collection",
expected.similar(jaObjObj));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jaRaw, jaStrObj, jaStrInt, jaStrObj
)));
}
@@ -553,6 +555,7 @@ public class JSONObjectTest {
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected 0 key1 items", ((Map<?,?>)(JsonPath.read(doc, "$.key1"))).size() == 0);
assertTrue("expected \"key2\":java.lang.Exception","java.lang.Exception".equals(jsonObject.query("/key2")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -580,6 +583,7 @@ public class JSONObjectTest {
assertTrue("expected \"escapeStringKey\":\"h\be\tllo w\u1234orld!\"", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/escapeStringKey")));
assertTrue("expected \"intKey\":42", Long.valueOf("42").equals(jsonObject.query("/intKey")));
assertTrue("expected \"doubleKey\":-23.45e67", Double.valueOf("-23.45e67").equals(jsonObject.query("/doubleKey")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -620,6 +624,7 @@ public class JSONObjectTest {
assertTrue("expected 2 callbacks items", ((List<?>)(JsonPath.read(doc, "$.callbacks"))).size() == 2);
assertTrue("expected 0 handler items", ((Map<?,?>)(JsonPath.read(doc, "$.callbacks[0].handler"))).size() == 0);
assertTrue("expected 0 callbacks[1] items", ((Map<?,?>)(JsonPath.read(doc, "$.callbacks[1]"))).size() == 0);
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -655,6 +660,7 @@ public class JSONObjectTest {
// InterfaceField replaces someFloat property name via user-defined annotation
assertTrue("Overridden String field name (InterfaceField) should have been found",
jsonObject.has("InterfaceField"));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -705,6 +711,7 @@ public class JSONObjectTest {
// property name able was replaced by Getable via user-defined annotation
assertTrue("Overridden boolean field name (Getable) should have been found",
jsonObject.has("Getable"));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -725,6 +732,7 @@ public class JSONObjectTest {
assertTrue("expected 2 top level items", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 2);
assertTrue("expected \"publicString\":\"abc\"", "abc".equals(jsonObject.query("/publicString")));
assertTrue("expected \"publicInt\":42", Integer.valueOf(42).equals(jsonObject.query("/publicInt")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -746,6 +754,7 @@ public class JSONObjectTest {
assertTrue("expected 2 farewells items", ((Map<?,?>)(JsonPath.read(doc, "$.farewells"))).size() == 2);
assertTrue("expected \"later\":\"Later, \"", "Later, ".equals(jsonObject.query("/farewells/later")));
assertTrue("expected \"world\":\"World!\"", "Alligator!".equals(jsonObject.query("/farewells/gator")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -778,6 +787,7 @@ public class JSONObjectTest {
assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/myArray/3")));
assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/myArray/4")));
assertTrue("expected -23.45e7", Double.valueOf(-23.45e7).equals(jsonObject.query("/myArray/5")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -809,6 +819,7 @@ public class JSONObjectTest {
assertTrue("expected h\be\tllo w\u1234orld!", "h\be\tllo w\u1234orld!".equals(jsonObject.query("/myArray/3")));
assertTrue("expected 42", Integer.valueOf(42).equals(jsonObject.query("/myArray/4")));
assertTrue("expected -23.45e7", Double.valueOf(-23.45e7).equals(jsonObject.query("/myArray/5")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -944,6 +955,7 @@ public class JSONObjectTest {
JSONObject jsonObjectInner = jsonObject.getJSONObject("objectKey");
assertTrue("objectKey should be JSONObject",
jsonObjectInner.get("myKey").equals("myVal"));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1006,6 +1018,7 @@ public class JSONObjectTest {
obj = jsonObject.get( "largeExponent" );
assertTrue("largeExponent should evaluate as a BigDecimal",
new BigDecimal("-23.45e2327").equals(obj));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1054,6 +1067,7 @@ public class JSONObjectTest {
jsonObject.get("floatIdentifier").equals(Double.valueOf(0.1)));
assertTrue("doubleIdentifier currently evaluates to double 0.1",
jsonObject.get("doubleIdentifier").equals(Double.valueOf(0.1)));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1205,6 +1219,7 @@ public class JSONObjectTest {
"JSONObject[\"stringKey\"] is not a JSONObject (class java.lang.String : hello world!).",
e.getMessage());
}
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1232,6 +1247,7 @@ public class JSONObjectTest {
assertTrue("3.0 can still be interpreted as a double",
deserialized.getDouble(key30) == 3.0);
assertTrue("3.1 remains a double", deserialized.getDouble(key31) == 3.1);
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1247,9 +1263,9 @@ public class JSONObjectTest {
* value is stored. This should be fixed.
*/
BigInteger bigInteger = new BigInteger("123456789012345678901234567890");
JSONObject jsonObject = new JSONObject(bigInteger);
Object obj = jsonObject.get("lowestSetBit");
assertTrue("JSONObject only has 1 value", jsonObject.length() == 1);
JSONObject jsonObject0 = new JSONObject(bigInteger);
Object obj = jsonObject0.get("lowestSetBit");
assertTrue("JSONObject only has 1 value", jsonObject0.length() == 1);
assertTrue("JSONObject parses BigInteger as the Integer lowestBitSet",
obj instanceof Integer);
assertTrue("this bigInteger lowestBitSet happens to be 1",
@@ -1262,57 +1278,57 @@ public class JSONObjectTest {
*/
BigDecimal bigDecimal = new BigDecimal(
"123456789012345678901234567890.12345678901234567890123456789");
jsonObject = new JSONObject(bigDecimal);
assertTrue("large bigDecimal is not stored", jsonObject.isEmpty());
JSONObject jsonObject1 = new JSONObject(bigDecimal);
assertTrue("large bigDecimal is not stored", jsonObject1.isEmpty());
/**
* JSONObject put(String, Object) method stores and serializes
* bigInt and bigDec correctly. Nothing needs to change.
*/
jsonObject = new JSONObject();
jsonObject.put("bigInt", bigInteger);
JSONObject jsonObject2 = new JSONObject();
jsonObject2.put("bigInt", bigInteger);
assertTrue("jsonObject.put() handles bigInt correctly",
jsonObject.get("bigInt").equals(bigInteger));
jsonObject2.get("bigInt").equals(bigInteger));
assertTrue("jsonObject.getBigInteger() handles bigInt correctly",
jsonObject.getBigInteger("bigInt").equals(bigInteger));
jsonObject2.getBigInteger("bigInt").equals(bigInteger));
assertTrue("jsonObject.optBigInteger() handles bigInt correctly",
jsonObject.optBigInteger("bigInt", BigInteger.ONE).equals(bigInteger));
jsonObject2.optBigInteger("bigInt", BigInteger.ONE).equals(bigInteger));
assertTrue("jsonObject serializes bigInt correctly",
jsonObject.toString().equals("{\"bigInt\":123456789012345678901234567890}"));
jsonObject2.toString().equals("{\"bigInt\":123456789012345678901234567890}"));
assertTrue("BigInteger as BigDecimal",
jsonObject.getBigDecimal("bigInt").equals(new BigDecimal(bigInteger)));
jsonObject2.getBigDecimal("bigInt").equals(new BigDecimal(bigInteger)));
jsonObject = new JSONObject();
jsonObject.put("bigDec", bigDecimal);
JSONObject jsonObject3 = new JSONObject();
jsonObject3.put("bigDec", bigDecimal);
assertTrue("jsonObject.put() handles bigDec correctly",
jsonObject.get("bigDec").equals(bigDecimal));
jsonObject3.get("bigDec").equals(bigDecimal));
assertTrue("jsonObject.getBigDecimal() handles bigDec correctly",
jsonObject.getBigDecimal("bigDec").equals(bigDecimal));
jsonObject3.getBigDecimal("bigDec").equals(bigDecimal));
assertTrue("jsonObject.optBigDecimal() handles bigDec correctly",
jsonObject.optBigDecimal("bigDec", BigDecimal.ONE).equals(bigDecimal));
jsonObject3.optBigDecimal("bigDec", BigDecimal.ONE).equals(bigDecimal));
assertTrue("jsonObject serializes bigDec correctly",
jsonObject.toString().equals(
jsonObject3.toString().equals(
"{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}"));
assertTrue("BigDecimal as BigInteger",
jsonObject.getBigInteger("bigDec").equals(bigDecimal.toBigInteger()));
jsonObject3.getBigInteger("bigDec").equals(bigDecimal.toBigInteger()));
/**
* exercise some exceptions
*/
try {
// bigInt key does not exist
jsonObject.getBigDecimal("bigInt");
jsonObject3.getBigDecimal("bigInt");
fail("expected an exeption");
} catch (JSONException ignored) {}
obj = jsonObject.optBigDecimal("bigInt", BigDecimal.ONE);
obj = jsonObject3.optBigDecimal("bigInt", BigDecimal.ONE);
assertTrue("expected BigDecimal", obj.equals(BigDecimal.ONE));
jsonObject.put("stringKey", "abc");
jsonObject3.put("stringKey", "abc");
try {
jsonObject.getBigDecimal("stringKey");
jsonObject3.getBigDecimal("stringKey");
fail("expected an exeption");
} catch (JSONException ignored) {}
obj = jsonObject.optBigInteger("bigDec", BigInteger.ONE);
obj = jsonObject3.optBigInteger("bigDec", BigInteger.ONE);
assertTrue("expected BigInteger", obj instanceof BigInteger);
assertEquals(bigDecimal.toBigInteger(), obj);
@@ -1345,79 +1361,79 @@ public class JSONObjectTest {
// bigInt map ctor
Map<String, Object> map = new HashMap<String, Object>();
map.put("bigInt", bigInteger);
jsonObject = new JSONObject(map);
String actualFromMapStr = jsonObject.toString();
JSONObject jsonObject4 = new JSONObject(map);
String actualFromMapStr = jsonObject4.toString();
assertTrue("bigInt in map (or array or bean) is a string",
actualFromMapStr.equals(
"{\"bigInt\":123456789012345678901234567890}"));
// bigInt put
jsonObject = new JSONObject();
jsonObject.put("bigInt", bigInteger);
String actualFromPutStr = jsonObject.toString();
JSONObject jsonObject5 = new JSONObject();
jsonObject5.put("bigInt", bigInteger);
String actualFromPutStr = jsonObject5.toString();
assertTrue("bigInt from put is a number",
actualFromPutStr.equals(
"{\"bigInt\":123456789012345678901234567890}"));
// bigDec map ctor
map = new HashMap<String, Object>();
map.put("bigDec", bigDecimal);
jsonObject = new JSONObject(map);
actualFromMapStr = jsonObject.toString();
JSONObject jsonObject6 = new JSONObject(map);
actualFromMapStr = jsonObject6.toString();
assertTrue("bigDec in map (or array or bean) is a bigDec",
actualFromMapStr.equals(
"{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}"));
// bigDec put
jsonObject = new JSONObject();
jsonObject.put("bigDec", bigDecimal);
actualFromPutStr = jsonObject.toString();
JSONObject jsonObject7 = new JSONObject();
jsonObject7.put("bigDec", bigDecimal);
actualFromPutStr = jsonObject7.toString();
assertTrue("bigDec from put is a number",
actualFromPutStr.equals(
"{\"bigDec\":123456789012345678901234567890.12345678901234567890123456789}"));
// bigInt,bigDec put
JSONArray jsonArray = new JSONArray();
jsonArray.put(bigInteger);
jsonArray.put(bigDecimal);
actualFromPutStr = jsonArray.toString();
JSONArray jsonArray0 = new JSONArray();
jsonArray0.put(bigInteger);
jsonArray0.put(bigDecimal);
actualFromPutStr = jsonArray0.toString();
assertTrue("bigInt, bigDec from put is a number",
actualFromPutStr.equals(
"[123456789012345678901234567890,123456789012345678901234567890.12345678901234567890123456789]"));
assertTrue("getBigInt is bigInt", jsonArray.getBigInteger(0).equals(bigInteger));
assertTrue("getBigDec is bigDec", jsonArray.getBigDecimal(1).equals(bigDecimal));
assertTrue("optBigInt is bigInt", jsonArray.optBigInteger(0, BigInteger.ONE).equals(bigInteger));
assertTrue("optBigDec is bigDec", jsonArray.optBigDecimal(1, BigDecimal.ONE).equals(bigDecimal));
jsonArray.put(Boolean.TRUE);
assertTrue("getBigInt is bigInt", jsonArray0.getBigInteger(0).equals(bigInteger));
assertTrue("getBigDec is bigDec", jsonArray0.getBigDecimal(1).equals(bigDecimal));
assertTrue("optBigInt is bigInt", jsonArray0.optBigInteger(0, BigInteger.ONE).equals(bigInteger));
assertTrue("optBigDec is bigDec", jsonArray0.optBigDecimal(1, BigDecimal.ONE).equals(bigDecimal));
jsonArray0.put(Boolean.TRUE);
try {
jsonArray.getBigInteger(2);
jsonArray0.getBigInteger(2);
fail("should not be able to get big int");
} catch (Exception ignored) {}
try {
jsonArray.getBigDecimal(2);
jsonArray0.getBigDecimal(2);
fail("should not be able to get big dec");
} catch (Exception ignored) {}
assertTrue("optBigInt is default", jsonArray.optBigInteger(2, BigInteger.ONE).equals(BigInteger.ONE));
assertTrue("optBigDec is default", jsonArray.optBigDecimal(2, BigDecimal.ONE).equals(BigDecimal.ONE));
assertTrue("optBigInt is default", jsonArray0.optBigInteger(2, BigInteger.ONE).equals(BigInteger.ONE));
assertTrue("optBigDec is default", jsonArray0.optBigDecimal(2, BigDecimal.ONE).equals(BigDecimal.ONE));
// bigInt,bigDec list ctor
List<Object> list = new ArrayList<Object>();
list.add(bigInteger);
list.add(bigDecimal);
jsonArray = new JSONArray(list);
String actualFromListStr = jsonArray.toString();
JSONArray jsonArray1 = new JSONArray(list);
String actualFromListStr = jsonArray1.toString();
assertTrue("bigInt, bigDec in list is a bigInt, bigDec",
actualFromListStr.equals(
"[123456789012345678901234567890,123456789012345678901234567890.12345678901234567890123456789]"));
// bigInt bean ctor
MyBigNumberBean myBigNumberBean = mock(MyBigNumberBean.class);
when(myBigNumberBean.getBigInteger()).thenReturn(new BigInteger("123456789012345678901234567890"));
jsonObject = new JSONObject(myBigNumberBean);
String actualFromBeanStr = jsonObject.toString();
JSONObject jsonObject8 = new JSONObject(myBigNumberBean);
String actualFromBeanStr = jsonObject8.toString();
// can't do a full string compare because mockery adds an extra key/value
assertTrue("bigInt from bean ctor is a bigInt",
actualFromBeanStr.contains("123456789012345678901234567890"));
// bigDec bean ctor
myBigNumberBean = mock(MyBigNumberBean.class);
when(myBigNumberBean.getBigDecimal()).thenReturn(new BigDecimal("123456789012345678901234567890.12345678901234567890123456789"));
jsonObject = new JSONObject(myBigNumberBean);
actualFromBeanStr = jsonObject.toString();
jsonObject8 = new JSONObject(myBigNumberBean);
actualFromBeanStr = jsonObject8.toString();
// can't do a full string compare because mockery adds an extra key/value
assertTrue("bigDec from bean ctor is a bigDec",
actualFromBeanStr.contains("123456789012345678901234567890.12345678901234567890123456789"));
@@ -1426,7 +1442,12 @@ public class JSONObjectTest {
assertTrue("wrap() returns big num",obj.equals(bigInteger));
obj = JSONObject.wrap(bigDecimal);
assertTrue("wrap() returns string",obj.equals(bigDecimal));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObject0, jsonObject1, jsonObject2, jsonObject3, jsonObject4,
jsonObject5, jsonObject6, jsonObject7, jsonObject8
)));
Util.checkJSONArrayMaps(jsonArray0, jsonObject0.getMapType());
Util.checkJSONArrayMaps(jsonArray1, jsonObject0.getMapType());
}
/**
@@ -1438,7 +1459,6 @@ public class JSONObjectTest {
*/
@Test
public void jsonObjectNames() {
JSONObject jsonObject;
// getNames() from null JSONObject
assertTrue("null names from null Object",
@@ -1449,16 +1469,16 @@ public class JSONObjectTest {
null == JSONObject.getNames(new MyJsonString()));
// getNames from new JSONOjbect
jsonObject = new JSONObject();
String [] names = JSONObject.getNames(jsonObject);
JSONObject jsonObject0 = new JSONObject();
String [] names = JSONObject.getNames(jsonObject0);
assertTrue("names should be null", names == null);
// getNames() from empty JSONObject
String emptyStr = "{}";
jsonObject = new JSONObject(emptyStr);
JSONObject jsonObject1 = new JSONObject(emptyStr);
assertTrue("empty JSONObject should have null names",
null == JSONObject.getNames(jsonObject));
null == JSONObject.getNames(jsonObject1));
// getNames() from JSONObject
String str =
@@ -1467,13 +1487,13 @@ public class JSONObjectTest {
"\"falseKey\":false,"+
"\"stringKey\":\"hello world!\","+
"}";
jsonObject = new JSONObject(str);
names = JSONObject.getNames(jsonObject);
JSONArray jsonArray = new JSONArray(names);
JSONObject jsonObject2 = new JSONObject(str);
names = JSONObject.getNames(jsonObject2);
JSONArray jsonArray0 = new JSONArray(names);
// validate JSON
Object doc = Configuration.defaultConfiguration().jsonProvider()
.parse(jsonArray.toString());
.parse(jsonArray0.toString());
List<?> docList = JsonPath.read(doc, "$");
assertTrue("expected 3 items", docList.size() == 3);
assertTrue(
@@ -1494,9 +1514,9 @@ public class JSONObjectTest {
names = JSONObject.getNames(myEnumField);
// validate JSON
jsonArray = new JSONArray(names);
JSONArray jsonArray1 = new JSONArray(names);
doc = Configuration.defaultConfiguration().jsonProvider()
.parse(jsonArray.toString());
.parse(jsonArray1.toString());
docList = JsonPath.read(doc, "$");
assertTrue("expected 3 items", docList.size() == 3);
assertTrue(
@@ -1518,9 +1538,9 @@ public class JSONObjectTest {
names = JSONObject.getNames(myPublicClass);
// validate JSON
jsonArray = new JSONArray(names);
JSONArray jsonArray2 = new JSONArray(names);
doc = Configuration.defaultConfiguration().jsonProvider()
.parse(jsonArray.toString());
.parse(jsonArray2.toString());
docList = JsonPath.read(doc, "$");
assertTrue("expected 2 items", docList.size() == 2);
assertTrue(
@@ -1529,6 +1549,12 @@ public class JSONObjectTest {
assertTrue(
"expected to find publicInt",
((List<?>) JsonPath.read(doc, "$[?(@=='publicInt')]")).size() == 1);
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObject0, jsonObject1, jsonObject2
)));
Util.checkJSONArrayMaps(jsonArray0, jsonObject0.getMapType());
Util.checkJSONArrayMaps(jsonArray1, jsonObject0.getMapType());
Util.checkJSONArrayMaps(jsonArray2, jsonObject0.getMapType());
}
/**
@@ -1540,6 +1566,8 @@ public class JSONObjectTest {
JSONObject jsonObject = new JSONObject();
JSONArray jsonArray = jsonObject.names();
assertTrue("jsonArray should be null", jsonArray == null);
Util.checkJSONObjectMaps(jsonObject);
Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType());
}
/**
@@ -1564,6 +1592,8 @@ public class JSONObjectTest {
assertTrue("expected to find trueKey", ((List<?>) JsonPath.read(doc, "$[?(@=='trueKey')]")).size() == 1);
assertTrue("expected to find falseKey", ((List<?>) JsonPath.read(doc, "$[?(@=='falseKey')]")).size() == 1);
assertTrue("expected to find stringKey", ((List<?>) JsonPath.read(doc, "$[?(@=='stringKey')]")).size() == 1);
Util.checkJSONObjectMaps(jsonObject);
Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType());
}
/**
@@ -1682,7 +1712,9 @@ public class JSONObjectTest {
// this.put(key, new Float((Float) value + 1));
// Probably it would be better to deprecate the method and remove some day, while convenient processing the "payload" is not
// really in the scope of a JSON-library (IMHO.)
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObject, inc
)));
}
/**
@@ -1780,6 +1812,12 @@ public class JSONObjectTest {
JSONObject bCompareArrayJsonObject = new JSONObject(bCompareArrayStr);
assertTrue("different nested JSONArrays should not be similar",
!aCompareArrayJsonObject.similar(bCompareArrayJsonObject));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObject, expectedJsonObject, aCompareValueJsonObject,
aCompareArrayJsonObject, aCompareObjectJsonObject, aCompareArrayJsonObject,
bCompareValueJsonObject, bCompareArrayJsonObject, bCompareObjectJsonObject,
bCompareArrayJsonObject
)));
}
/**
@@ -1815,6 +1853,7 @@ public class JSONObjectTest {
assertTrue("expected myVal2", "myVal2".equals(jsonObject.query("/objectKey/myKey2")));
assertTrue("expected myVal3", "myVal3".equals(jsonObject.query("/objectKey/myKey3")));
assertTrue("expected myVal4", "myVal4".equals(jsonObject.query("/objectKey/myKey4")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1888,6 +1927,9 @@ public class JSONObjectTest {
JSONObject jo = new JSONObject().put("TABLE", new JSONObject().put("yhoo", new JSONObject()));
assertEquals("toString(2)","{\"TABLE\": {\"yhoo\": {}}}", jo.toString(2));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObject, jo
)));
}
/**
@@ -1909,6 +1951,7 @@ public class JSONObjectTest {
assertTrue("expected 1 top level item", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 1);
assertTrue("expected 1 key item", ((Map<?,?>)(JsonPath.read(doc, "$.key"))).size() == 1);
assertTrue("expected def", "def".equals(jsonObject.query("/key/abc")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1931,6 +1974,7 @@ public class JSONObjectTest {
assertTrue("expected 1 top level item", ((Map<?,?>)(JsonPath.read(doc, "$"))).size() == 1);
assertTrue("expected 1 key item", ((List<?>)(JsonPath.read(doc, "$.key"))).size() == 1);
assertTrue("expected abc", "abc".equals(jsonObject.query("/key/0")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -1978,7 +2022,9 @@ public class JSONObjectTest {
jsonArray.toString().equals(JSONObject.valueToString(collection)));
Integer[] array = { new Integer(1), new Integer(2), new Integer(3) };
assertTrue("array valueToString() incorrect",
jsonArray.toString().equals(JSONObject.valueToString(array)));
jsonArray.toString().equals(JSONObject.valueToString(array)));
Util.checkJSONObjectMaps(jsonObject);
Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType());
}
/**
@@ -2082,6 +2128,11 @@ public class JSONObjectTest {
assertTrue("expected val1", "val1".equals(mapJsonObject.query("/key1")));
assertTrue("expected val2", "val2".equals(mapJsonObject.query("/key2")));
assertTrue("expected val3", "val3".equals(mapJsonObject.query("/key3")));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObject, mapJsonObject
)));
Util.checkJSONArrayMaps(jsonArray, jsonObject.getMapType());
Util.checkJSONArrayMaps(integerArrayJsonArray, jsonObject.getMapType());
}
@@ -2096,6 +2147,7 @@ public class JSONObjectTest {
try {
JSONObject jo = new JSONObject(source);
assertTrue("Expected "+charString+"("+i+") in the JSON Object but did not find it.",charString.equals(jo.getString("key")));
Util.checkJSONObjectMaps(jo);
} catch (JSONException ex) {
assertTrue("Only \\0 (U+0000), \\n (U+000A), and \\r (U+000D) should cause an error. Instead "+charString+"("+i+") caused an error",
i=='\0' || i=='\n' || i=='\r'
@@ -2395,6 +2447,7 @@ public class JSONObjectTest {
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
jsonObject.putOnce(null, "");
assertTrue("jsonObject should be empty", jsonObject.isEmpty());
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2430,6 +2483,7 @@ public class JSONObjectTest {
42l == jsonObject.optNumber("myKey", Long.valueOf(42)).longValue());
assertTrue("optString() should return default string",
"hi".equals(jsonObject.optString("hiKey", "hi")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2466,6 +2520,7 @@ public class JSONObjectTest {
42l == jsonObject.optNumber("myKey", Long.valueOf(42)).longValue());
assertTrue("optString() should return default string",
"hi".equals(jsonObject.optString("hiKey", "hi")));
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2484,6 +2539,7 @@ public class JSONObjectTest {
assertTrue("unexpected optBigDecimal value",jo.optBigDecimal("int",BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0);
assertTrue("unexpected optBigDecimal value",jo.optBigDecimal("int",BigDecimal.ZERO).compareTo(new BigDecimal("123"))==0);
assertTrue("unexpected optNumber value",jo.optNumber("int",BigInteger.ZERO).longValue()==123l);
Util.checkJSONObjectMaps(jo);
}
/**
@@ -2518,6 +2574,7 @@ public class JSONObjectTest {
assertNotEquals((int)Double.parseDouble("19007199254740993.35481234487103587486413587843213584"), jo.optInt("largeNumberStr"));
assertEquals(19007199254740992l, (long)Double.parseDouble("19007199254740993.35481234487103587486413587843213584"));
assertEquals(2147483647, (int)Double.parseDouble("19007199254740993.35481234487103587486413587843213584"));
Util.checkJSONObjectMaps(jo);
}
/**
@@ -2540,6 +2597,7 @@ public class JSONObjectTest {
assertNull(jo.optBigDecimal("nullVal", null));
assertEquals(jo.optBigDecimal("float", null),jo.getBigDecimal("float"));
assertEquals(jo.optBigDecimal("double", null),jo.getBigDecimal("double"));
Util.checkJSONObjectMaps(jo);
}
/**
@@ -2560,6 +2618,7 @@ public class JSONObjectTest {
assertEquals(new BigInteger("1234"),jo.optBigInteger("bigInteger", null));
assertEquals(new BigInteger("1234"),jo.optBigInteger("bigDecimal", null));
assertNull(jo.optBigDecimal("nullVal", null));
Util.checkJSONObjectMaps(jo);
}
/**
@@ -2577,8 +2636,9 @@ public class JSONObjectTest {
JSONObject jsonObjectPutNull = new JSONObject(str);
jsonObjectPutNull.put("myKey", (Object) null);
assertTrue("jsonObject should be empty", jsonObjectPutNull.isEmpty());
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObjectRemove, jsonObjectPutNull
)));
}
/**
@@ -2663,6 +2723,7 @@ public class JSONObjectTest {
} finally {
stringWriter.close();
}
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2745,7 +2806,7 @@ public class JSONObjectTest {
writer.close();
} catch (Exception e) {}
}
Util.checkJSONObjectMaps(jsonObject);
}
@@ -2813,6 +2874,7 @@ public class JSONObjectTest {
stringWriter.close();
} catch (Exception e) {}
}
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -2855,6 +2917,7 @@ public class JSONObjectTest {
JSONObject aJsonObject = new JSONObject(str);
assertTrue("Same JSONObject should be equal to itself",
aJsonObject.equals(aJsonObject));
Util.checkJSONObjectMaps(aJsonObject);
}
/**
@@ -2940,6 +3003,9 @@ public class JSONObjectTest {
"<key>null</key>".equals(sJONull));
String sNull = XML.toString(jsonObjectNull);
assertTrue("null should emit an empty string", "".equals(sNull));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jsonObjectJONull, jsonObjectNull
)));
}
@Test(expected = JSONPointerException.class)
@@ -3037,6 +3103,7 @@ public class JSONObjectTest {
// assert that the new map is mutable
assertTrue("Removing a key should succeed", map.remove("key3") != null);
assertTrue("Map should have 2 elements", map.size() == 2);
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -3061,6 +3128,9 @@ public class JSONObjectTest {
// ensure our original jo hasn't changed.
assertEquals(0, jo.get("someInt"));
assertEquals(null, jo.opt("someString"));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jo, jo2
)));
}
/**
@@ -3085,6 +3155,9 @@ public class JSONObjectTest {
// ensure our original jo hasn't changed.
assertEquals(0, jo.get("someInt"));
assertEquals(null, jo.opt("someString"));
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
jo, jo2
)));
}
/**
@@ -3100,6 +3173,7 @@ public class JSONObjectTest {
assertEquals("Expected the getter to only be called once",
1, bean.genericGetCounter);
assertEquals(0, bean.genericSetCounter);
Util.checkJSONObjectMaps(jo);
}
/**
@@ -3115,6 +3189,7 @@ public class JSONObjectTest {
assertEquals("Expected the getter to only be called once",
1, bean.genericGetCounter);
assertEquals(0, bean.genericSetCounter);
Util.checkJSONObjectMaps(jo);
}
/**
@@ -3133,6 +3208,7 @@ public class JSONObjectTest {
assertEquals("Expected 1 key to be mapped. Instead found: "+jo.keySet().toString(),
1, jo.length());
assertNotNull(jo.get("ALL"));
Util.checkJSONObjectMaps(jo);
}
/**
@@ -3150,6 +3226,8 @@ public class JSONObjectTest {
BigDecimal wantedValue = BigDecimal.valueOf(value);
assertEquals(current, wantedValue);
Util.checkJSONObjectMaps(jsonObject);
Util.checkJSONArrayMaps(array, jsonObject.getMapType());
}
/**
@@ -3163,6 +3241,7 @@ public class JSONObjectTest {
1, jo.length());
assertTrue(jo.get("closeable") instanceof JSONObject);
assertTrue(jo.getJSONObject("closeable").has("string"));
Util.checkJSONObjectMaps(jo);
}
@Test(expected=NullPointerException.class)
@@ -3289,9 +3368,12 @@ public class JSONObjectTest {
ObjC.setRef(ObjA);
ObjB.setRef(ObjA);
ObjB.setRef2(ObjA);
new JSONObject(ObjC);
new JSONObject(ObjB);
new JSONObject(ObjA);
JSONObject j0 = new JSONObject(ObjC);
JSONObject j1 = new JSONObject(ObjB);
JSONObject j2 = new JSONObject(ObjA);
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
j0, j1, j2
)));
}
@Test
public void testLongRepeatObjectNotRecursive() {
@@ -3307,17 +3389,21 @@ public class JSONObjectTest {
ObjB.setRef2(ObjD);
ObjA.setRef(ObjD);
ObjD.setRef(ObjE);
new JSONObject(ObjC);
new JSONObject(ObjB);
new JSONObject(ObjA);
new JSONObject(ObjD);
new JSONObject(ObjE);
JSONObject j0 = new JSONObject(ObjC);
JSONObject j1 = new JSONObject(ObjB);
JSONObject j2 = new JSONObject(ObjA);
JSONObject j3 = new JSONObject(ObjD);
JSONObject j4 = new JSONObject(ObjE);
Util.checkJSONObjectsMaps(new ArrayList<JSONObject>(Arrays.asList(
j0, j1, j2, j3, j4
)));
}
@Test(expected=JSONException.class)
public void testRecursiveEquals() {
RecursiveBeanEquals a = new RecursiveBeanEquals("same");
a.setRef(a);
new JSONObject(a);
JSONObject j0 = new JSONObject(a);
Util.checkJSONObjectMaps(j0);
}
@Test
public void testNotRecursiveEquals() {
@@ -3326,7 +3412,8 @@ public class JSONObjectTest {
RecursiveBeanEquals c = new RecursiveBeanEquals("same");
a.setRef(b);
b.setRef(c);
new JSONObject(a);
JSONObject j0 = new JSONObject(a);
Util.checkJSONObjectMaps(j0);
}
@@ -3336,6 +3423,7 @@ public class JSONObjectTest {
assertTrue("missing expected key 'empty_json_array'", jsonObject.has("empty_json_array"));
assertNotNull("'empty_json_array' should be an array", jsonObject.getJSONArray("empty_json_array"));
assertEquals("'empty_json_array' should have a length of 0", 0, jsonObject.getJSONArray("empty_json_array").length());
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -3351,6 +3439,7 @@ public class JSONObjectTest {
jsonObject.clear(); //Clears the JSONObject
assertTrue("expected jsonObject.length() == 0", jsonObject.length() == 0); //Check if its length is 0
jsonObject.getInt("key1"); //Should throws org.json.JSONException: JSONObject["asd"] not found
Util.checkJSONObjectMaps(jsonObject);
}
/**
@@ -3364,6 +3453,7 @@ public class JSONObjectTest {
JSONObject json_input = new JSONObject(input);
assertNotNull(json_input);
fail("Excepected Exception.");
Util.checkJSONObjectMaps(json_input);
}
/**
@@ -3373,7 +3463,7 @@ public class JSONObjectTest {
public void issue654IncorrectNestingNoKey1() {
JSONObject json_input = new JSONObject("{{\"a\":0}}");
assertNotNull(json_input);
fail("Excepected Exception.");
fail("Expected Exception.");
}
/**
@@ -3398,4 +3488,25 @@ public class JSONObjectTest {
assertNotNull(json_input);
fail("Excepected Exception.");
}
@Test
public void testIssue682SimilarityOfJSONString() {
JSONObject jo1 = new JSONObject()
.put("a", new MyJsonString())
.put("b", 2);
JSONObject jo2 = new JSONObject()
.put("a", new MyJsonString())
.put("b", 2);
assertTrue(jo1.similar(jo2));
JSONObject jo3 = new JSONObject()
.put("a", new JSONString() {
@Override
public String toJSONString() {
return "\"different value\"";
}
})
.put("b", 2);
assertFalse(jo1.similar(jo3));
}
}

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -92,8 +72,10 @@ public class JSONPointerTest {
@Test
public void queryByEmptyKeySubObject() {
assertEquals( "{\"\":\"empty key of an object with an empty key\",\"subKey\":\"Some" +
" other value\"}", query("/obj/").toString());
JSONObject json = new JSONObject("{\"\":\"empty key of an object with an empty key\",\"subKey\":\"Some" +
" other value\"}");
JSONObject obj = (JSONObject) query("/obj/");
assertTrue(json.similar(obj));
}
@Test

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.assertEquals;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import java.util.*;

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.*;
@@ -78,7 +58,6 @@ public class Util {
* or something else.
* @param value created by the code to be tested
* @param expectedValue created specifically for comparing
* @param key key to the jsonObject entry to be compared
*/
private static void compareActualVsExpectedObjects(Object value,
Object expectedValue) {
@@ -117,4 +96,106 @@ public class Util {
);
}
}
/**
* Asserts that all JSONObject maps are the same as the default ctor
* @param jsonObjects list of objects to be tested
*/
public static void checkJSONObjectsMaps(List<JSONObject> jsonObjects) {
if (jsonObjects == null || jsonObjects.size() == 0) {
return;
}
Class<? extends Map> mapType = new JSONObject().getMapType();
for (JSONObject jsonObject : jsonObjects) {
if (jsonObject != null) {
assertTrue(mapType == jsonObject.getMapType());
checkJSONObjectMaps(jsonObject, mapType);
}
}
}
/**
* Asserts that all JSONObject maps are the same as the default ctor
* @param jsonObject the object to be tested
*/
public static void checkJSONObjectMaps(JSONObject jsonObject) {
if (jsonObject != null) {
checkJSONObjectMaps(jsonObject, jsonObject.getMapType());
}
}
/**
* Asserts that all JSONObject maps are the same as mapType
* @param jsonObject object to be tested
* @param mapType mapType to test against
*/
public static void checkJSONObjectMaps(JSONObject jsonObject, Class<? extends Map> mapType) {
if (mapType == null) {
mapType = new JSONObject().getMapType();
}
Set<String> keys = jsonObject.keySet();
for (String key : keys) {
Object val = jsonObject.get(key);
if (val instanceof JSONObject) {
JSONObject jsonObjectVal = (JSONObject) val;
assertTrue(mapType == ((JSONObject) val).getMapType());
checkJSONObjectMaps(jsonObjectVal, mapType);
} else if (val instanceof JSONArray) {
JSONArray jsonArrayVal = (JSONArray)val;
checkJSONArrayMaps(jsonArrayVal, mapType);
}
}
}
/**
* Asserts that all JSONObject maps in the JSONArray object match the default map
* @param jsonArrays list of JSONArray objects to be tested
*/
public static void checkJSONArraysMaps(List<JSONArray> jsonArrays) {
if (jsonArrays == null || jsonArrays.size() == 0) {
return;
}
Class<? extends Map> mapType = new JSONObject().getMapType();
for (JSONArray jsonArray : jsonArrays) {
if (jsonArray != null) {
checkJSONArrayMaps(jsonArray, mapType);
}
}
}
/**
* Asserts that all JSONObject maps in the JSONArray object match mapType
* @param jsonArray object to be tested
* @param mapType map type to be tested against
*/
public static void checkJSONArrayMaps(JSONArray jsonArray, Class<? extends Map> mapType) {
if (jsonArray == null) {
return;
}
if (mapType == null) {
mapType = new JSONObject().getMapType();
}
Iterator<Object> it = jsonArray.iterator();
while (it.hasNext()) {
Object val = it.next();
if (val instanceof JSONObject) {
JSONObject jsonObjectVal = (JSONObject)val;
checkJSONObjectMaps(jsonObjectVal, mapType);
} else if (val instanceof JSONArray) {
JSONArray jsonArrayVal = (JSONArray)val;
checkJSONArrayMaps(jsonArrayVal, mapType);
}
}
}
/**
* Asserts that all JSONObject maps nested in the JSONArray match
* the default mapType
* @param jsonArray the object to be tested
*/
public static void checkJSONArrayMaps(JSONArray jsonArray) {
if (jsonArray != null) {
checkJSONArrayMaps(jsonArray, null);
}
}
}

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -1071,6 +1051,29 @@ public class XMLConfigurationTest {
Util.compareActualVsExpectedJsonObjects(jsonObject, expetedJsonObject);
}
@Test
public void testMaxNestingDepthIsSet() {
XMLParserConfiguration xmlParserConfiguration = XMLParserConfiguration.ORIGINAL;
assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.DEFAULT_MAXIMUM_NESTING_DEPTH);
xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(42);
assertEquals(xmlParserConfiguration.getMaxNestingDepth(), 42);
xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(0);
assertEquals(xmlParserConfiguration.getMaxNestingDepth(), 0);
xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(-31415926);
assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH);
xmlParserConfiguration = xmlParserConfiguration.withMaxNestingDepth(Integer.MIN_VALUE);
assertEquals(xmlParserConfiguration.getMaxNestingDepth(), XMLParserConfiguration.UNDEFINED_MAXIMUM_NESTING_DEPTH);
}
/**
* Convenience method, given an input string and expected result,

View File

@@ -1,27 +1,7 @@
package org.json.junit;
/*
Copyright (c) 2020 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Public Domain.
*/
import static org.junit.Assert.assertEquals;
@@ -41,13 +21,7 @@ import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.json.XML;
import org.json.XMLParserConfiguration;
import org.json.XMLXsiTypeConverter;
import org.json.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -1069,4 +1043,270 @@ public class XMLTest {
fail("Expected to be unable to modify the config");
} catch (Exception ignored) { }
}
@Test
public void testIndentComplicatedJsonObject(){
String str = "{\n" +
" \"success\": true,\n" +
" \"error\": null,\n" +
" \"response\": [\n" +
" {\n" +
" \"timestamp\": 1664917200,\n" +
" \"dateTimeISO\": \"2022-10-05T00:00:00+03:00\",\n" +
" \"loc\": {\n" +
" \"lat\": 39.91987,\n" +
" \"long\": 32.85427\n" +
" },\n" +
" \"place\": {\n" +
" \"name\": \"ankara\",\n" +
" \"state\": \"an\",\n" +
" \"country\": \"tr\"\n" +
" },\n" +
" \"profile\": {\n" +
" \"tz\": \"Europe/Istanbul\"\n" +
" },\n" +
" \"sun\": {\n" +
" \"rise\": 1664941721,\n" +
" \"riseISO\": \"2022-10-05T06:48:41+03:00\",\n" +
" \"set\": 1664983521,\n" +
" \"setISO\": \"2022-10-05T18:25:21+03:00\",\n" +
" \"transit\": 1664962621,\n" +
" \"transitISO\": \"2022-10-05T12:37:01+03:00\",\n" +
" \"midnightSun\": false,\n" +
" \"polarNight\": false,\n" +
" \"twilight\": {\n" +
" \"civilBegin\": 1664940106,\n" +
" \"civilBeginISO\": \"2022-10-05T06:21:46+03:00\",\n" +
" \"civilEnd\": 1664985136,\n" +
" \"civilEndISO\": \"2022-10-05T18:52:16+03:00\",\n" +
" \"nauticalBegin\": 1664938227,\n" +
" \"nauticalBeginISO\": \"2022-10-05T05:50:27+03:00\",\n" +
" \"nauticalEnd\": 1664987015,\n" +
" \"nauticalEndISO\": \"2022-10-05T19:23:35+03:00\",\n" +
" \"astronomicalBegin\": 1664936337,\n" +
" \"astronomicalBeginISO\": \"2022-10-05T05:18:57+03:00\",\n" +
" \"astronomicalEnd\": 1664988905,\n" +
" \"astronomicalEndISO\": \"2022-10-05T19:55:05+03:00\"\n" +
" }\n" +
" },\n" +
" \"moon\": {\n" +
" \"rise\": 1664976480,\n" +
" \"riseISO\": \"2022-10-05T16:28:00+03:00\",\n" +
" \"set\": 1664921520,\n" +
" \"setISO\": \"2022-10-05T01:12:00+03:00\",\n" +
" \"transit\": 1664994240,\n" +
" \"transitISO\": \"2022-10-05T21:24:00+03:00\",\n" +
" \"underfoot\": 1664949360,\n" +
" \"underfootISO\": \"2022-10-05T08:56:00+03:00\",\n" +
" \"phase\": {\n" +
" \"phase\": 0.3186,\n" +
" \"name\": \"waxing gibbous\",\n" +
" \"illum\": 71,\n" +
" \"age\": 9.41,\n" +
" \"angle\": 0.55\n" +
" }\n" +
" }\n" +
" }\n" +
" ]\n" +
"}" ;
JSONObject jsonObject = new JSONObject(str);
String actualIndentedXmlString = XML.toString(jsonObject, 1);
String expected = "<success>true</success>\n" +
"<response>\n" +
" <dateTimeISO>2022-10-05T00:00:00+03:00</dateTimeISO>\n" +
" <loc>\n" +
" <lat>39.91987</lat>\n" +
" <long>32.85427</long>\n" +
" </loc>\n" +
" <moon>\n" +
" <phase>\n" +
" <phase>0.3186</phase>\n" +
" <name>waxing gibbous</name>\n" +
" <angle>0.55</angle>\n" +
" <illum>71</illum>\n" +
" <age>9.41</age>\n" +
" </phase>\n" +
" <setISO>2022-10-05T01:12:00+03:00</setISO>\n" +
" <underfoot>1664949360</underfoot>\n" +
" <set>1664921520</set>\n" +
" <transit>1664994240</transit>\n" +
" <transitISO>2022-10-05T21:24:00+03:00</transitISO>\n" +
" <riseISO>2022-10-05T16:28:00+03:00</riseISO>\n" +
" <rise>1664976480</rise>\n" +
" <underfootISO>2022-10-05T08:56:00+03:00</underfootISO>\n" +
" </moon>\n" +
" <profile>\n" +
" <tz>Europe/Istanbul</tz>\n" +
" </profile>\n" +
" <place>\n" +
" <country>tr</country>\n" +
" <name>ankara</name>\n" +
" <state>an</state>\n" +
" </place>\n" +
" <sun>\n" +
" <setISO>2022-10-05T18:25:21+03:00</setISO>\n" +
" <midnightSun>false</midnightSun>\n" +
" <set>1664983521</set>\n" +
" <transit>1664962621</transit>\n" +
" <polarNight>false</polarNight>\n" +
" <transitISO>2022-10-05T12:37:01+03:00</transitISO>\n" +
" <riseISO>2022-10-05T06:48:41+03:00</riseISO>\n" +
" <rise>1664941721</rise>\n" +
" <twilight>\n" +
" <civilEnd>1664985136</civilEnd>\n" +
" <astronomicalBegin>1664936337</astronomicalBegin>\n" +
" <astronomicalEnd>1664988905</astronomicalEnd>\n" +
" <astronomicalBeginISO>2022-10-05T05:18:57+03:00</astronomicalBeginISO>\n" +
" <civilBegin>1664940106</civilBegin>\n" +
" <nauticalEndISO>2022-10-05T19:23:35+03:00</nauticalEndISO>\n" +
" <astronomicalEndISO>2022-10-05T19:55:05+03:00</astronomicalEndISO>\n" +
" <nauticalBegin>1664938227</nauticalBegin>\n" +
" <nauticalEnd>1664987015</nauticalEnd>\n" +
" <nauticalBeginISO>2022-10-05T05:50:27+03:00</nauticalBeginISO>\n" +
" <civilBeginISO>2022-10-05T06:21:46+03:00</civilBeginISO>\n" +
" <civilEndISO>2022-10-05T18:52:16+03:00</civilEndISO>\n" +
" </twilight>\n" +
" </sun>\n" +
" <timestamp>1664917200</timestamp>\n" +
"</response>\n" +
"<error>null</error>\n";
assertEquals(actualIndentedXmlString, expected);
}
@Test
public void testIndentSimpleJsonObject(){
String str = "{ \"employee\": { \n" +
" \"name\": \"sonoo\", \n" +
" \"salary\": 56000, \n" +
" \"married\": true \n" +
" }}";
JSONObject jsonObject = new JSONObject(str);
String actual = XML.toString(jsonObject, "Test", 2);
String expected = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
assertEquals(actual, expected);
}
@Test
public void testIndentSimpleJsonArray(){
String str = "[ \n" +
" {\"name\":\"Ram\", \"email\":\"Ram@gmail.com\"}, \n" +
" {\"name\":\"Bob\", \"email\":\"bob32@gmail.com\"} \n" +
"] ";
JSONArray jsonObject = new JSONArray(str);
String actual = XML.toString(jsonObject, 2);
String expected = "<array>\n" +
" <name>Ram</name>\n" +
" <email>Ram@gmail.com</email>\n" +
"</array>\n" +
"<array>\n" +
" <name>Bob</name>\n" +
" <email>bob32@gmail.com</email>\n" +
"</array>\n";
assertEquals(actual, expected);
}
@Test
public void testIndentComplicatedJsonObjectWithArrayAndWithConfig(){
try {
InputStream jsonStream = null;
try {
jsonStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.json");
final JSONObject object = new JSONObject(new JSONTokener(jsonStream));
String actualString = XML.toString(object, null, XMLParserConfiguration.KEEP_STRINGS,2);
InputStream xmlStream = null;
try {
xmlStream = XMLTest.class.getClassLoader().getResourceAsStream("Issue593.xml");
int bufferSize = 1024;
char[] buffer = new char[bufferSize];
StringBuilder expected = new StringBuilder();
Reader in = new InputStreamReader(xmlStream, "UTF-8");
for (int numRead; (numRead = in.read(buffer, 0, buffer.length)) > 0; ) {
expected.append(buffer, 0, numRead);
}
assertEquals(expected.toString(), actualString.replaceAll("\\n|\\r\\n", System.getProperty("line.separator")));
} finally {
if (xmlStream != null) {
xmlStream.close();
}
}
} finally {
if (jsonStream != null) {
jsonStream.close();
}
}
} catch (IOException e) {
fail("file writer error: " +e.getMessage());
}
}
@Test
public void testMaxNestingDepthOf42IsRespected() {
final String wayTooLongMalformedXML = new String(new char[6000]).replace("\0", "<a>");
final int maxNestingDepth = 42;
try {
XML.toJSONObject(wayTooLongMalformedXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testMaxNestingDepthIsRespectedWithValidXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 1;
try {
XML.toJSONObject(perfectlyFineXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
fail("Expecting a JSONException");
} catch (JSONException e) {
assertTrue("Wrong throwable thrown: not expecting message <" + e.getMessage() + ">",
e.getMessage().startsWith("Maximum nesting depth of " + maxNestingDepth));
}
}
@Test
public void testMaxNestingDepthWithValidFittingXML() {
final String perfectlyFineXML = "<Test>\n" +
" <employee>\n" +
" <name>sonoo</name>\n" +
" <salary>56000</salary>\n" +
" <married>true</married>\n" +
" </employee>\n" +
"</Test>\n";
final int maxNestingDepth = 3;
try {
XML.toJSONObject(perfectlyFineXML, XMLParserConfiguration.ORIGINAL.withMaxNestingDepth(maxNestingDepth));
} catch (JSONException e) {
e.printStackTrace();
fail("XML document should be parsed as its maximum depth fits the maxNestingDepth " +
"parameter of the XMLParserConfiguration used");
}
}
}

View File

@@ -0,0 +1,704 @@
{
"success": true,
"error": null,
"response": [
{
"loc": {
"long": 31.25,
"lat": 30.063
},
"interval": "day",
"place": {
"name": "cairo",
"state": "qh",
"country": "eg"
},
"periods": [
{
"timestamp": 1665032400,
"validTime": "2022-10-06T07:00:00+02:00",
"dateTimeISO": "2022-10-06T07:00:00+02:00",
"maxTempC": 32,
"maxTempF": 90,
"minTempC": 19,
"minTempF": 66,
"avgTempC": 25,
"avgTempF": 78,
"tempC": null,
"tempF": null,
"maxFeelslikeC": 32,
"maxFeelslikeF": 89,
"minFeelslikeC": 21,
"minFeelslikeF": 70,
"avgFeelslikeC": 26,
"avgFeelslikeF": 80,
"feelslikeC": 21,
"feelslikeF": 70,
"maxDewpointC": 17,
"maxDewpointF": 63,
"minDewpointC": 11,
"minDewpointF": 52,
"avgDewpointC": 14,
"avgDewpointF": 58,
"dewpointC": 17,
"dewpointF": 63,
"maxHumidity": 77,
"minHumidity": 29,
"humidity": 77,
"pop": 0,
"precipMM": 0,
"precipIN": 0,
"iceaccum": null,
"iceaccumMM": null,
"iceaccumIN": null,
"snowCM": 0,
"snowIN": 0,
"pressureMB": 1015,
"pressureIN": 29.97,
"windDir": "N",
"windDirDEG": 353,
"windSpeedKTS": 5,
"windSpeedKPH": 9,
"windSpeedMPH": 6,
"windGustKTS": 21,
"windGustKPH": 40,
"windGustMPH": 25,
"windDirMax": "NNW",
"windDirMaxDEG": 342,
"windSpeedMaxKTS": 9,
"windSpeedMaxKPH": 16,
"windSpeedMaxMPH": 10,
"windDirMin": "N",
"windDirMinDEG": 353,
"windSpeedMinKTS": 1,
"windSpeedMinKPH": 2,
"windSpeedMinMPH": 1,
"windDir80m": "N",
"windDir80mDEG": 11,
"windSpeed80mKTS": 12,
"windSpeed80mKPH": 22,
"windSpeed80mMPH": 13,
"windGust80mKTS": 22,
"windGust80mKPH": 41,
"windGust80mMPH": 25,
"windDirMax80m": "NNW",
"windDirMax80mDEG": 343,
"windSpeedMax80mKTS": 22,
"windSpeedMax80mKPH": 41,
"windSpeedMax80mMPH": 25,
"windDirMin80m": "E",
"windDirMin80mDEG": 95,
"windSpeedMin80mKTS": 8,
"windSpeedMin80mKPH": 15,
"windSpeedMin80mMPH": 10,
"sky": 22,
"cloudsCoded": "FW",
"weather": "Mostly Sunny",
"weatherCoded": [],
"weatherPrimary": "Mostly Sunny",
"weatherPrimaryCoded": "::FW",
"icon": "fair.png",
"visibilityKM": 24.135,
"visibilityMI": 15,
"uvi": 6,
"solradWM2": 5608,
"solradMinWM2": 0,
"solradMaxWM2": 778,
"isDay": true,
"maxCoverage": "",
"sunrise": 1665028274,
"sunset": 1665070502,
"sunriseISO": "2022-10-06T05:51:14+02:00",
"sunsetISO": "2022-10-06T17:35:02+02:00"
},
{
"timestamp": 1665118800,
"validTime": "2022-10-07T07:00:00+02:00",
"dateTimeISO": "2022-10-07T07:00:00+02:00",
"maxTempC": 30,
"maxTempF": 86,
"minTempC": 19,
"minTempF": 66,
"avgTempC": 24,
"avgTempF": 76,
"tempC": null,
"tempF": null,
"maxFeelslikeC": 29,
"maxFeelslikeF": 85,
"minFeelslikeC": 19,
"minFeelslikeF": 67,
"avgFeelslikeC": 24,
"avgFeelslikeF": 76,
"feelslikeC": 19,
"feelslikeF": 67,
"maxDewpointC": 15,
"maxDewpointF": 60,
"minDewpointC": 10,
"minDewpointF": 50,
"avgDewpointC": 12,
"avgDewpointF": 54,
"dewpointC": 15,
"dewpointF": 60,
"maxHumidity": 77,
"minHumidity": 30,
"humidity": 77,
"pop": 0,
"precipMM": 0,
"precipIN": 0,
"iceaccum": null,
"iceaccumMM": null,
"iceaccumIN": null,
"snowCM": 0,
"snowIN": 0,
"pressureMB": 1014,
"pressureIN": 29.95,
"windDir": "NW",
"windDirDEG": 325,
"windSpeedKTS": 1,
"windSpeedKPH": 2,
"windSpeedMPH": 1,
"windGustKTS": 16,
"windGustKPH": 29,
"windGustMPH": 18,
"windDirMax": "WNW",
"windDirMaxDEG": 298,
"windSpeedMaxKTS": 7,
"windSpeedMaxKPH": 13,
"windSpeedMaxMPH": 8,
"windDirMin": "NW",
"windDirMinDEG": 325,
"windSpeedMinKTS": 1,
"windSpeedMinKPH": 2,
"windSpeedMinMPH": 1,
"windDir80m": "NNW",
"windDir80mDEG": 347,
"windSpeed80mKTS": 6,
"windSpeed80mKPH": 10,
"windSpeed80mMPH": 6,
"windGust80mKTS": 20,
"windGust80mKPH": 37,
"windGust80mMPH": 23,
"windDirMax80m": "NW",
"windDirMax80mDEG": 316,
"windSpeedMax80mKTS": 20,
"windSpeedMax80mKPH": 37,
"windSpeedMax80mMPH": 23,
"windDirMin80m": "NNW",
"windDirMin80mDEG": 347,
"windSpeedMin80mKTS": 6,
"windSpeedMin80mKPH": 10,
"windSpeedMin80mMPH": 6,
"sky": 30,
"cloudsCoded": "FW",
"weather": "Mostly Sunny",
"weatherCoded": [],
"weatherPrimary": "Mostly Sunny",
"weatherPrimaryCoded": "::FW",
"icon": "fair.png",
"visibilityKM": 24.135,
"visibilityMI": 15,
"uvi": 6,
"solradWM2": 5486,
"solradMinWM2": 0,
"solradMaxWM2": 742,
"isDay": true,
"maxCoverage": "",
"sunrise": 1665114710,
"sunset": 1665156831,
"sunriseISO": "2022-10-07T05:51:50+02:00",
"sunsetISO": "2022-10-07T17:33:51+02:00"
},
{
"timestamp": 1665205200,
"validTime": "2022-10-08T07:00:00+02:00",
"dateTimeISO": "2022-10-08T07:00:00+02:00",
"maxTempC": 30,
"maxTempF": 87,
"minTempC": 19,
"minTempF": 66,
"avgTempC": 25,
"avgTempF": 76,
"tempC": null,
"tempF": null,
"maxFeelslikeC": 30,
"maxFeelslikeF": 86,
"minFeelslikeC": 19,
"minFeelslikeF": 67,
"avgFeelslikeC": 25,
"avgFeelslikeF": 76,
"feelslikeC": 19,
"feelslikeF": 67,
"maxDewpointC": 15,
"maxDewpointF": 59,
"minDewpointC": 11,
"minDewpointF": 52,
"avgDewpointC": 13,
"avgDewpointF": 56,
"dewpointC": 15,
"dewpointF": 59,
"maxHumidity": 76,
"minHumidity": 32,
"humidity": 76,
"pop": 0,
"precipMM": 0,
"precipIN": 0,
"iceaccum": null,
"iceaccumMM": null,
"iceaccumIN": null,
"snowCM": 0,
"snowIN": 0,
"pressureMB": 1014,
"pressureIN": 29.94,
"windDir": "NNE",
"windDirDEG": 21,
"windSpeedKTS": 1,
"windSpeedKPH": 2,
"windSpeedMPH": 1,
"windGustKTS": 17,
"windGustKPH": 32,
"windGustMPH": 20,
"windDirMax": "WNW",
"windDirMaxDEG": 301,
"windSpeedMaxKTS": 7,
"windSpeedMaxKPH": 13,
"windSpeedMaxMPH": 8,
"windDirMin": "NNE",
"windDirMinDEG": 21,
"windSpeedMinKTS": 1,
"windSpeedMinKPH": 2,
"windSpeedMinMPH": 1,
"windDir80m": "NW",
"windDir80mDEG": 309,
"windSpeed80mKTS": 5,
"windSpeed80mKPH": 9,
"windSpeed80mMPH": 5,
"windGust80mKTS": 17,
"windGust80mKPH": 31,
"windGust80mMPH": 19,
"windDirMax80m": "NW",
"windDirMax80mDEG": 322,
"windSpeedMax80mKTS": 17,
"windSpeedMax80mKPH": 31,
"windSpeedMax80mMPH": 19,
"windDirMin80m": "NW",
"windDirMin80mDEG": 309,
"windSpeedMin80mKTS": 5,
"windSpeedMin80mKPH": 9,
"windSpeedMin80mMPH": 5,
"sky": 47,
"cloudsCoded": "SC",
"weather": "Partly Cloudy",
"weatherCoded": [],
"weatherPrimary": "Partly Cloudy",
"weatherPrimaryCoded": "::SC",
"icon": "pcloudy.png",
"visibilityKM": 24.135,
"visibilityMI": 15,
"uvi": 7,
"solradWM2": 4785,
"solradMinWM2": 0,
"solradMaxWM2": 682,
"isDay": true,
"maxCoverage": "",
"sunrise": 1665201146,
"sunset": 1665243161,
"sunriseISO": "2022-10-08T05:52:26+02:00",
"sunsetISO": "2022-10-08T17:32:41+02:00"
},
{
"timestamp": 1665291600,
"validTime": "2022-10-09T07:00:00+02:00",
"dateTimeISO": "2022-10-09T07:00:00+02:00",
"maxTempC": 31,
"maxTempF": 87,
"minTempC": 19,
"minTempF": 67,
"avgTempC": 25,
"avgTempF": 77,
"tempC": null,
"tempF": null,
"maxFeelslikeC": 30,
"maxFeelslikeF": 86,
"minFeelslikeC": 20,
"minFeelslikeF": 67,
"avgFeelslikeC": 25,
"avgFeelslikeF": 77,
"feelslikeC": 20,
"feelslikeF": 67,
"maxDewpointC": 17,
"maxDewpointF": 63,
"minDewpointC": 11,
"minDewpointF": 52,
"avgDewpointC": 14,
"avgDewpointF": 57,
"dewpointC": 17,
"dewpointF": 63,
"maxHumidity": 86,
"minHumidity": 31,
"humidity": 86,
"pop": 0,
"precipMM": 0,
"precipIN": 0,
"iceaccum": null,
"iceaccumMM": null,
"iceaccumIN": null,
"snowCM": 0,
"snowIN": 0,
"pressureMB": 1016,
"pressureIN": 29.99,
"windDir": "N",
"windDirDEG": 356,
"windSpeedKTS": 2,
"windSpeedKPH": 4,
"windSpeedMPH": 2,
"windGustKTS": 19,
"windGustKPH": 36,
"windGustMPH": 22,
"windDirMax": "NNW",
"windDirMaxDEG": 343,
"windSpeedMaxKTS": 8,
"windSpeedMaxKPH": 14,
"windSpeedMaxMPH": 9,
"windDirMin": "N",
"windDirMinDEG": 356,
"windSpeedMinKTS": 2,
"windSpeedMinKPH": 4,
"windSpeedMinMPH": 2,
"windDir80m": "NW",
"windDir80mDEG": 316,
"windSpeed80mKTS": 5,
"windSpeed80mKPH": 9,
"windSpeed80mMPH": 6,
"windGust80mKTS": 20,
"windGust80mKPH": 36,
"windGust80mMPH": 23,
"windDirMax80m": "N",
"windDirMax80mDEG": 354,
"windSpeedMax80mKTS": 20,
"windSpeedMax80mKPH": 36,
"windSpeedMax80mMPH": 23,
"windDirMin80m": "NW",
"windDirMin80mDEG": 316,
"windSpeedMin80mKTS": 5,
"windSpeedMin80mKPH": 9,
"windSpeedMin80mMPH": 6,
"sky": 47,
"cloudsCoded": "SC",
"weather": "Partly Cloudy",
"weatherCoded": [],
"weatherPrimary": "Partly Cloudy",
"weatherPrimaryCoded": "::SC",
"icon": "pcloudy.png",
"visibilityKM": 24.135,
"visibilityMI": 15,
"uvi": 7,
"solradWM2": 4768,
"solradMinWM2": 0,
"solradMaxWM2": 726,
"isDay": true,
"maxCoverage": "",
"sunrise": 1665287583,
"sunset": 1665329491,
"sunriseISO": "2022-10-09T05:53:03+02:00",
"sunsetISO": "2022-10-09T17:31:31+02:00"
},
{
"timestamp": 1665378000,
"validTime": "2022-10-10T07:00:00+02:00",
"dateTimeISO": "2022-10-10T07:00:00+02:00",
"maxTempC": 31,
"maxTempF": 87,
"minTempC": 21,
"minTempF": 70,
"avgTempC": 26,
"avgTempF": 78,
"tempC": null,
"tempF": null,
"maxFeelslikeC": 30,
"maxFeelslikeF": 86,
"minFeelslikeC": 21,
"minFeelslikeF": 69,
"avgFeelslikeC": 25,
"avgFeelslikeF": 78,
"feelslikeC": 21,
"feelslikeF": 69,
"maxDewpointC": 16,
"maxDewpointF": 61,
"minDewpointC": 13,
"minDewpointF": 55,
"avgDewpointC": 14,
"avgDewpointF": 58,
"dewpointC": 16,
"dewpointF": 61,
"maxHumidity": 75,
"minHumidity": 35,
"humidity": 75,
"pop": 0,
"precipMM": 0,
"precipIN": 0,
"iceaccum": null,
"iceaccumMM": null,
"iceaccumIN": null,
"snowCM": 0,
"snowIN": 0,
"pressureMB": 1017,
"pressureIN": 30.03,
"windDir": "N",
"windDirDEG": 358,
"windSpeedKTS": 2,
"windSpeedKPH": 4,
"windSpeedMPH": 2,
"windGustKTS": 16,
"windGustKPH": 30,
"windGustMPH": 19,
"windDirMax": "N",
"windDirMaxDEG": 10,
"windSpeedMaxKTS": 8,
"windSpeedMaxKPH": 15,
"windSpeedMaxMPH": 9,
"windDirMin": "N",
"windDirMinDEG": 358,
"windSpeedMinKTS": 2,
"windSpeedMinKPH": 4,
"windSpeedMinMPH": 2,
"windDir80m": "N",
"windDir80mDEG": 8,
"windSpeed80mKTS": 7,
"windSpeed80mKPH": 13,
"windSpeed80mMPH": 8,
"windGust80mKTS": 19,
"windGust80mKPH": 36,
"windGust80mMPH": 22,
"windDirMax80m": "N",
"windDirMax80mDEG": 10,
"windSpeedMax80mKTS": 19,
"windSpeedMax80mKPH": 36,
"windSpeedMax80mMPH": 22,
"windDirMin80m": "E",
"windDirMin80mDEG": 91,
"windSpeedMin80mKTS": 7,
"windSpeedMin80mKPH": 13,
"windSpeedMin80mMPH": 8,
"sky": 64,
"cloudsCoded": "SC",
"weather": "Partly Cloudy",
"weatherCoded": [],
"weatherPrimary": "Partly Cloudy",
"weatherPrimaryCoded": "::SC",
"icon": "pcloudy.png",
"visibilityKM": 24.135,
"visibilityMI": 15,
"uvi": 6,
"solradWM2": 4494,
"solradMinWM2": 0,
"solradMaxWM2": 597,
"isDay": true,
"maxCoverage": "",
"sunrise": 1665374020,
"sunset": 1665415821,
"sunriseISO": "2022-10-10T05:53:40+02:00",
"sunsetISO": "2022-10-10T17:30:21+02:00"
},
{
"timestamp": 1665464400,
"validTime": "2022-10-11T07:00:00+02:00",
"dateTimeISO": "2022-10-11T07:00:00+02:00",
"maxTempC": 31,
"maxTempF": 87,
"minTempC": 21,
"minTempF": 70,
"avgTempC": 26,
"avgTempF": 78,
"tempC": null,
"tempF": null,
"maxFeelslikeC": 31,
"maxFeelslikeF": 87,
"minFeelslikeC": 22,
"minFeelslikeF": 72,
"avgFeelslikeC": 26,
"avgFeelslikeF": 79,
"feelslikeC": 22,
"feelslikeF": 72,
"maxDewpointC": 17,
"maxDewpointF": 62,
"minDewpointC": 11,
"minDewpointF": 51,
"avgDewpointC": 13,
"avgDewpointF": 55,
"dewpointC": 17,
"dewpointF": 62,
"maxHumidity": 71,
"minHumidity": 30,
"humidity": 71,
"pop": 0,
"precipMM": 0,
"precipIN": 0,
"iceaccum": null,
"iceaccumMM": null,
"iceaccumIN": null,
"snowCM": 0,
"snowIN": 0,
"pressureMB": 1015,
"pressureIN": 29.98,
"windDir": "NNE",
"windDirDEG": 13,
"windSpeedKTS": 8,
"windSpeedKPH": 15,
"windSpeedMPH": 9,
"windGustKTS": 15,
"windGustKPH": 28,
"windGustMPH": 17,
"windDirMax": "NNE",
"windDirMaxDEG": 28,
"windSpeedMaxKTS": 15,
"windSpeedMaxKPH": 28,
"windSpeedMaxMPH": 18,
"windDirMin": "NNE",
"windDirMinDEG": 14,
"windSpeedMinKTS": 7,
"windSpeedMinKPH": 14,
"windSpeedMinMPH": 8,
"windDir80m": "NNE",
"windDir80mDEG": 16,
"windSpeed80mKTS": 10,
"windSpeed80mKPH": 19,
"windSpeed80mMPH": 12,
"windGust80mKTS": 17,
"windGust80mKPH": 31,
"windGust80mMPH": 19,
"windDirMax80m": "NNE",
"windDirMax80mDEG": 28,
"windSpeedMax80mKTS": 17,
"windSpeedMax80mKPH": 31,
"windSpeedMax80mMPH": 19,
"windDirMin80m": "NNE",
"windDirMin80mDEG": 13,
"windSpeedMin80mKTS": 9,
"windSpeedMin80mKPH": 18,
"windSpeedMin80mMPH": 11,
"sky": 0,
"cloudsCoded": "CL",
"weather": "Sunny",
"weatherCoded": [],
"weatherPrimary": "Sunny",
"weatherPrimaryCoded": "::CL",
"icon": "sunny.png",
"visibilityKM": 24.135,
"visibilityMI": 15,
"uvi": null,
"solradWM2": 5450,
"solradMinWM2": 0,
"solradMaxWM2": 758,
"isDay": true,
"maxCoverage": "",
"sunrise": 1665460458,
"sunset": 1665502153,
"sunriseISO": "2022-10-11T05:54:18+02:00",
"sunsetISO": "2022-10-11T17:29:13+02:00"
},
{
"timestamp": 1665550800,
"validTime": "2022-10-12T07:00:00+02:00",
"dateTimeISO": "2022-10-12T07:00:00+02:00",
"maxTempC": 31,
"maxTempF": 88,
"minTempC": 21,
"minTempF": 69,
"avgTempC": 26,
"avgTempF": 79,
"tempC": null,
"tempF": null,
"maxFeelslikeC": 31,
"maxFeelslikeF": 88,
"minFeelslikeC": 22,
"minFeelslikeF": 72,
"avgFeelslikeC": 26,
"avgFeelslikeF": 80,
"feelslikeC": 22,
"feelslikeF": 72,
"maxDewpointC": 16,
"maxDewpointF": 60,
"minDewpointC": 11,
"minDewpointF": 51,
"avgDewpointC": 13,
"avgDewpointF": 55,
"dewpointC": 16,
"dewpointF": 60,
"maxHumidity": 68,
"minHumidity": 29,
"humidity": 68,
"pop": 0,
"precipMM": 0,
"precipIN": 0,
"iceaccum": null,
"iceaccumMM": null,
"iceaccumIN": null,
"snowCM": 0,
"snowIN": 0,
"pressureMB": 1014,
"pressureIN": 29.95,
"windDir": "NNE",
"windDirDEG": 12,
"windSpeedKTS": 8,
"windSpeedKPH": 15,
"windSpeedMPH": 9,
"windGustKTS": 15,
"windGustKPH": 28,
"windGustMPH": 17,
"windDirMax": "E",
"windDirMaxDEG": 96,
"windSpeedMaxKTS": 14,
"windSpeedMaxKPH": 26,
"windSpeedMaxMPH": 16,
"windDirMin": "NNE",
"windDirMinDEG": 12,
"windSpeedMinKTS": 7,
"windSpeedMinKPH": 13,
"windSpeedMinMPH": 8,
"windDir80m": "NNE",
"windDir80mDEG": 15,
"windSpeed80mKTS": 10,
"windSpeed80mKPH": 19,
"windSpeed80mMPH": 12,
"windGust80mKTS": 18,
"windGust80mKPH": 33,
"windGust80mMPH": 21,
"windDirMax80m": "E",
"windDirMax80mDEG": 96,
"windSpeedMax80mKTS": 18,
"windSpeedMax80mKPH": 33,
"windSpeedMax80mMPH": 21,
"windDirMin80m": "NNE",
"windDirMin80mDEG": 15,
"windSpeedMin80mKTS": 10,
"windSpeedMin80mKPH": 18,
"windSpeedMin80mMPH": 11,
"sky": 27,
"cloudsCoded": "FW",
"weather": "Mostly Sunny",
"weatherCoded": [],
"weatherPrimary": "Mostly Sunny",
"weatherPrimaryCoded": "::FW",
"icon": "fair.png",
"visibilityKM": 24.135,
"visibilityMI": 15,
"uvi": null,
"solradWM2": 4740,
"solradMinWM2": 0,
"solradMaxWM2": 743,
"isDay": true,
"maxCoverage": "",
"sunrise": 1665546895,
"sunset": 1665588484,
"sunriseISO": "2022-10-12T05:54:55+02:00",
"sunsetISO": "2022-10-12T17:28:04+02:00"
}
],
"profile": {
"tz": "Africa/Cairo",
"elevM": 23,
"elevFT": 75
}
}
]
}

View File

@@ -0,0 +1,691 @@
<success>true</success>
<response>
<loc>
<long>31.25</long>
<lat>30.063</lat>
</loc>
<profile>
<elevM>23</elevM>
<tz>Africa/Cairo</tz>
<elevFT>75</elevFT>
</profile>
<periods>
<dateTimeISO>2022-10-06T07:00:00+02:00</dateTimeISO>
<windDirMin80m>E</windDirMin80m>
<windDirMin80mDEG>95</windDirMin80mDEG>
<feelslikeC>21</feelslikeC>
<visibilityMI>15</visibilityMI>
<windSpeedMaxMPH>10</windSpeedMaxMPH>
<windDirDEG>353</windDirDEG>
<windDir>N</windDir>
<sunriseISO>2022-10-06T05:51:14+02:00</sunriseISO>
<iceaccumMM>null</iceaccumMM>
<windSpeedMaxKTS>9</windSpeedMaxKTS>
<iceaccumIN>null</iceaccumIN>
<minTempF>66</minTempF>
<snowIN>0</snowIN>
<weather>Mostly Sunny</weather>
<sunsetISO>2022-10-06T17:35:02+02:00</sunsetISO>
<maxFeelslikeC>32</maxFeelslikeC>
<humidity>77</humidity>
<windDir80m>N</windDir80m>
<maxFeelslikeF>89</maxFeelslikeF>
<precipMM>0</precipMM>
<sky>22</sky>
<windGust80mMPH>25</windGust80mMPH>
<windSpeedMax80mMPH>25</windSpeedMax80mMPH>
<weatherPrimary>Mostly Sunny</weatherPrimary>
<windGust80mKPH>41</windGust80mKPH>
<avgDewpointF>58</avgDewpointF>
<windSpeedMax80mKPH>41</windSpeedMax80mKPH>
<windGust80mKTS>22</windGust80mKTS>
<avgDewpointC>14</avgDewpointC>
<precipIN>0</precipIN>
<windSpeedMax80mKTS>22</windSpeedMax80mKTS>
<windDirMinDEG>353</windDirMinDEG>
<windSpeedMaxKPH>16</windSpeedMaxKPH>
<windSpeedMin80mKTS>8</windSpeedMin80mKTS>
<feelslikeF>70</feelslikeF>
<validTime>2022-10-06T07:00:00+02:00</validTime>
<windSpeedMin80mMPH>10</windSpeedMin80mMPH>
<solradMaxWM2>778</solradMaxWM2>
<avgTempC>25</avgTempC>
<windSpeedMin80mKPH>15</windSpeedMin80mKPH>
<weatherPrimaryCoded>::FW</weatherPrimaryCoded>
<sunrise>1665028274</sunrise>
<avgTempF>78</avgTempF>
<windDirMin>N</windDirMin>
<maxCoverage/>
<icon>fair.png</icon>
<minFeelslikeC>21</minFeelslikeC>
<dewpointC>17</dewpointC>
<cloudsCoded>FW</cloudsCoded>
<minFeelslikeF>70</minFeelslikeF>
<minHumidity>29</minHumidity>
<dewpointF>63</dewpointF>
<windSpeed80mKTS>12</windSpeed80mKTS>
<pop>0</pop>
<snowCM>0</snowCM>
<windDirMax>NNW</windDirMax>
<windSpeed80mMPH>13</windSpeed80mMPH>
<windSpeed80mKPH>22</windSpeed80mKPH>
<windDir80mDEG>11</windDir80mDEG>
<maxTempC>32</maxTempC>
<pressureMB>1015</pressureMB>
<visibilityKM>24.135</visibilityKM>
<timestamp>1665032400</timestamp>
<maxTempF>90</maxTempF>
<tempF>null</tempF>
<minDewpointC>11</minDewpointC>
<solradMinWM2>0</solradMinWM2>
<windSpeedMinKTS>1</windSpeedMinKTS>
<windDirMax80mDEG>343</windDirMax80mDEG>
<windGustKTS>21</windGustKTS>
<windSpeedMinKPH>2</windSpeedMinKPH>
<maxDewpointF>63</maxDewpointF>
<windSpeedMinMPH>1</windSpeedMinMPH>
<avgFeelslikeC>26</avgFeelslikeC>
<uvi>6</uvi>
<windDirMax80m>NNW</windDirMax80m>
<maxDewpointC>17</maxDewpointC>
<pressureIN>29.97</pressureIN>
<avgFeelslikeF>80</avgFeelslikeF>
<iceaccum>null</iceaccum>
<isDay>true</isDay>
<minTempC>19</minTempC>
<minDewpointF>52</minDewpointF>
<windSpeedKTS>5</windSpeedKTS>
<sunset>1665070502</sunset>
<solradWM2>5608</solradWM2>
<windSpeedKPH>9</windSpeedKPH>
<windGustMPH>25</windGustMPH>
<maxHumidity>77</maxHumidity>
<windSpeedMPH>6</windSpeedMPH>
<windGustKPH>40</windGustKPH>
<windDirMaxDEG>342</windDirMaxDEG>
<tempC>null</tempC>
</periods>
<periods>
<dateTimeISO>2022-10-07T07:00:00+02:00</dateTimeISO>
<windDirMin80m>NNW</windDirMin80m>
<windDirMin80mDEG>347</windDirMin80mDEG>
<feelslikeC>19</feelslikeC>
<visibilityMI>15</visibilityMI>
<windSpeedMaxMPH>8</windSpeedMaxMPH>
<windDirDEG>325</windDirDEG>
<windDir>NW</windDir>
<sunriseISO>2022-10-07T05:51:50+02:00</sunriseISO>
<iceaccumMM>null</iceaccumMM>
<windSpeedMaxKTS>7</windSpeedMaxKTS>
<iceaccumIN>null</iceaccumIN>
<minTempF>66</minTempF>
<snowIN>0</snowIN>
<weather>Mostly Sunny</weather>
<sunsetISO>2022-10-07T17:33:51+02:00</sunsetISO>
<maxFeelslikeC>29</maxFeelslikeC>
<humidity>77</humidity>
<windDir80m>NNW</windDir80m>
<maxFeelslikeF>85</maxFeelslikeF>
<precipMM>0</precipMM>
<sky>30</sky>
<windGust80mMPH>23</windGust80mMPH>
<windSpeedMax80mMPH>23</windSpeedMax80mMPH>
<weatherPrimary>Mostly Sunny</weatherPrimary>
<windGust80mKPH>37</windGust80mKPH>
<avgDewpointF>54</avgDewpointF>
<windSpeedMax80mKPH>37</windSpeedMax80mKPH>
<windGust80mKTS>20</windGust80mKTS>
<avgDewpointC>12</avgDewpointC>
<precipIN>0</precipIN>
<windSpeedMax80mKTS>20</windSpeedMax80mKTS>
<windDirMinDEG>325</windDirMinDEG>
<windSpeedMaxKPH>13</windSpeedMaxKPH>
<windSpeedMin80mKTS>6</windSpeedMin80mKTS>
<feelslikeF>67</feelslikeF>
<validTime>2022-10-07T07:00:00+02:00</validTime>
<windSpeedMin80mMPH>6</windSpeedMin80mMPH>
<solradMaxWM2>742</solradMaxWM2>
<avgTempC>24</avgTempC>
<windSpeedMin80mKPH>10</windSpeedMin80mKPH>
<weatherPrimaryCoded>::FW</weatherPrimaryCoded>
<sunrise>1665114710</sunrise>
<avgTempF>76</avgTempF>
<windDirMin>NW</windDirMin>
<maxCoverage/>
<icon>fair.png</icon>
<minFeelslikeC>19</minFeelslikeC>
<dewpointC>15</dewpointC>
<cloudsCoded>FW</cloudsCoded>
<minFeelslikeF>67</minFeelslikeF>
<minHumidity>30</minHumidity>
<dewpointF>60</dewpointF>
<windSpeed80mKTS>6</windSpeed80mKTS>
<pop>0</pop>
<snowCM>0</snowCM>
<windDirMax>WNW</windDirMax>
<windSpeed80mMPH>6</windSpeed80mMPH>
<windSpeed80mKPH>10</windSpeed80mKPH>
<windDir80mDEG>347</windDir80mDEG>
<maxTempC>30</maxTempC>
<pressureMB>1014</pressureMB>
<visibilityKM>24.135</visibilityKM>
<timestamp>1665118800</timestamp>
<maxTempF>86</maxTempF>
<tempF>null</tempF>
<minDewpointC>10</minDewpointC>
<solradMinWM2>0</solradMinWM2>
<windSpeedMinKTS>1</windSpeedMinKTS>
<windDirMax80mDEG>316</windDirMax80mDEG>
<windGustKTS>16</windGustKTS>
<windSpeedMinKPH>2</windSpeedMinKPH>
<maxDewpointF>60</maxDewpointF>
<windSpeedMinMPH>1</windSpeedMinMPH>
<avgFeelslikeC>24</avgFeelslikeC>
<uvi>6</uvi>
<windDirMax80m>NW</windDirMax80m>
<maxDewpointC>15</maxDewpointC>
<pressureIN>29.95</pressureIN>
<avgFeelslikeF>76</avgFeelslikeF>
<iceaccum>null</iceaccum>
<isDay>true</isDay>
<minTempC>19</minTempC>
<minDewpointF>50</minDewpointF>
<windSpeedKTS>1</windSpeedKTS>
<sunset>1665156831</sunset>
<solradWM2>5486</solradWM2>
<windSpeedKPH>2</windSpeedKPH>
<windGustMPH>18</windGustMPH>
<maxHumidity>77</maxHumidity>
<windSpeedMPH>1</windSpeedMPH>
<windGustKPH>29</windGustKPH>
<windDirMaxDEG>298</windDirMaxDEG>
<tempC>null</tempC>
</periods>
<periods>
<dateTimeISO>2022-10-08T07:00:00+02:00</dateTimeISO>
<windDirMin80m>NW</windDirMin80m>
<windDirMin80mDEG>309</windDirMin80mDEG>
<feelslikeC>19</feelslikeC>
<visibilityMI>15</visibilityMI>
<windSpeedMaxMPH>8</windSpeedMaxMPH>
<windDirDEG>21</windDirDEG>
<windDir>NNE</windDir>
<sunriseISO>2022-10-08T05:52:26+02:00</sunriseISO>
<iceaccumMM>null</iceaccumMM>
<windSpeedMaxKTS>7</windSpeedMaxKTS>
<iceaccumIN>null</iceaccumIN>
<minTempF>66</minTempF>
<snowIN>0</snowIN>
<weather>Partly Cloudy</weather>
<sunsetISO>2022-10-08T17:32:41+02:00</sunsetISO>
<maxFeelslikeC>30</maxFeelslikeC>
<humidity>76</humidity>
<windDir80m>NW</windDir80m>
<maxFeelslikeF>86</maxFeelslikeF>
<precipMM>0</precipMM>
<sky>47</sky>
<windGust80mMPH>19</windGust80mMPH>
<windSpeedMax80mMPH>19</windSpeedMax80mMPH>
<weatherPrimary>Partly Cloudy</weatherPrimary>
<windGust80mKPH>31</windGust80mKPH>
<avgDewpointF>56</avgDewpointF>
<windSpeedMax80mKPH>31</windSpeedMax80mKPH>
<windGust80mKTS>17</windGust80mKTS>
<avgDewpointC>13</avgDewpointC>
<precipIN>0</precipIN>
<windSpeedMax80mKTS>17</windSpeedMax80mKTS>
<windDirMinDEG>21</windDirMinDEG>
<windSpeedMaxKPH>13</windSpeedMaxKPH>
<windSpeedMin80mKTS>5</windSpeedMin80mKTS>
<feelslikeF>67</feelslikeF>
<validTime>2022-10-08T07:00:00+02:00</validTime>
<windSpeedMin80mMPH>5</windSpeedMin80mMPH>
<solradMaxWM2>682</solradMaxWM2>
<avgTempC>25</avgTempC>
<windSpeedMin80mKPH>9</windSpeedMin80mKPH>
<weatherPrimaryCoded>::SC</weatherPrimaryCoded>
<sunrise>1665201146</sunrise>
<avgTempF>76</avgTempF>
<windDirMin>NNE</windDirMin>
<maxCoverage/>
<icon>pcloudy.png</icon>
<minFeelslikeC>19</minFeelslikeC>
<dewpointC>15</dewpointC>
<cloudsCoded>SC</cloudsCoded>
<minFeelslikeF>67</minFeelslikeF>
<minHumidity>32</minHumidity>
<dewpointF>59</dewpointF>
<windSpeed80mKTS>5</windSpeed80mKTS>
<pop>0</pop>
<snowCM>0</snowCM>
<windDirMax>WNW</windDirMax>
<windSpeed80mMPH>5</windSpeed80mMPH>
<windSpeed80mKPH>9</windSpeed80mKPH>
<windDir80mDEG>309</windDir80mDEG>
<maxTempC>30</maxTempC>
<pressureMB>1014</pressureMB>
<visibilityKM>24.135</visibilityKM>
<timestamp>1665205200</timestamp>
<maxTempF>87</maxTempF>
<tempF>null</tempF>
<minDewpointC>11</minDewpointC>
<solradMinWM2>0</solradMinWM2>
<windSpeedMinKTS>1</windSpeedMinKTS>
<windDirMax80mDEG>322</windDirMax80mDEG>
<windGustKTS>17</windGustKTS>
<windSpeedMinKPH>2</windSpeedMinKPH>
<maxDewpointF>59</maxDewpointF>
<windSpeedMinMPH>1</windSpeedMinMPH>
<avgFeelslikeC>25</avgFeelslikeC>
<uvi>7</uvi>
<windDirMax80m>NW</windDirMax80m>
<maxDewpointC>15</maxDewpointC>
<pressureIN>29.94</pressureIN>
<avgFeelslikeF>76</avgFeelslikeF>
<iceaccum>null</iceaccum>
<isDay>true</isDay>
<minTempC>19</minTempC>
<minDewpointF>52</minDewpointF>
<windSpeedKTS>1</windSpeedKTS>
<sunset>1665243161</sunset>
<solradWM2>4785</solradWM2>
<windSpeedKPH>2</windSpeedKPH>
<windGustMPH>20</windGustMPH>
<maxHumidity>76</maxHumidity>
<windSpeedMPH>1</windSpeedMPH>
<windGustKPH>32</windGustKPH>
<windDirMaxDEG>301</windDirMaxDEG>
<tempC>null</tempC>
</periods>
<periods>
<dateTimeISO>2022-10-09T07:00:00+02:00</dateTimeISO>
<windDirMin80m>NW</windDirMin80m>
<windDirMin80mDEG>316</windDirMin80mDEG>
<feelslikeC>20</feelslikeC>
<visibilityMI>15</visibilityMI>
<windSpeedMaxMPH>9</windSpeedMaxMPH>
<windDirDEG>356</windDirDEG>
<windDir>N</windDir>
<sunriseISO>2022-10-09T05:53:03+02:00</sunriseISO>
<iceaccumMM>null</iceaccumMM>
<windSpeedMaxKTS>8</windSpeedMaxKTS>
<iceaccumIN>null</iceaccumIN>
<minTempF>67</minTempF>
<snowIN>0</snowIN>
<weather>Partly Cloudy</weather>
<sunsetISO>2022-10-09T17:31:31+02:00</sunsetISO>
<maxFeelslikeC>30</maxFeelslikeC>
<humidity>86</humidity>
<windDir80m>NW</windDir80m>
<maxFeelslikeF>86</maxFeelslikeF>
<precipMM>0</precipMM>
<sky>47</sky>
<windGust80mMPH>23</windGust80mMPH>
<windSpeedMax80mMPH>23</windSpeedMax80mMPH>
<weatherPrimary>Partly Cloudy</weatherPrimary>
<windGust80mKPH>36</windGust80mKPH>
<avgDewpointF>57</avgDewpointF>
<windSpeedMax80mKPH>36</windSpeedMax80mKPH>
<windGust80mKTS>20</windGust80mKTS>
<avgDewpointC>14</avgDewpointC>
<precipIN>0</precipIN>
<windSpeedMax80mKTS>20</windSpeedMax80mKTS>
<windDirMinDEG>356</windDirMinDEG>
<windSpeedMaxKPH>14</windSpeedMaxKPH>
<windSpeedMin80mKTS>5</windSpeedMin80mKTS>
<feelslikeF>67</feelslikeF>
<validTime>2022-10-09T07:00:00+02:00</validTime>
<windSpeedMin80mMPH>6</windSpeedMin80mMPH>
<solradMaxWM2>726</solradMaxWM2>
<avgTempC>25</avgTempC>
<windSpeedMin80mKPH>9</windSpeedMin80mKPH>
<weatherPrimaryCoded>::SC</weatherPrimaryCoded>
<sunrise>1665287583</sunrise>
<avgTempF>77</avgTempF>
<windDirMin>N</windDirMin>
<maxCoverage/>
<icon>pcloudy.png</icon>
<minFeelslikeC>20</minFeelslikeC>
<dewpointC>17</dewpointC>
<cloudsCoded>SC</cloudsCoded>
<minFeelslikeF>67</minFeelslikeF>
<minHumidity>31</minHumidity>
<dewpointF>63</dewpointF>
<windSpeed80mKTS>5</windSpeed80mKTS>
<pop>0</pop>
<snowCM>0</snowCM>
<windDirMax>NNW</windDirMax>
<windSpeed80mMPH>6</windSpeed80mMPH>
<windSpeed80mKPH>9</windSpeed80mKPH>
<windDir80mDEG>316</windDir80mDEG>
<maxTempC>31</maxTempC>
<pressureMB>1016</pressureMB>
<visibilityKM>24.135</visibilityKM>
<timestamp>1665291600</timestamp>
<maxTempF>87</maxTempF>
<tempF>null</tempF>
<minDewpointC>11</minDewpointC>
<solradMinWM2>0</solradMinWM2>
<windSpeedMinKTS>2</windSpeedMinKTS>
<windDirMax80mDEG>354</windDirMax80mDEG>
<windGustKTS>19</windGustKTS>
<windSpeedMinKPH>4</windSpeedMinKPH>
<maxDewpointF>63</maxDewpointF>
<windSpeedMinMPH>2</windSpeedMinMPH>
<avgFeelslikeC>25</avgFeelslikeC>
<uvi>7</uvi>
<windDirMax80m>N</windDirMax80m>
<maxDewpointC>17</maxDewpointC>
<pressureIN>29.99</pressureIN>
<avgFeelslikeF>77</avgFeelslikeF>
<iceaccum>null</iceaccum>
<isDay>true</isDay>
<minTempC>19</minTempC>
<minDewpointF>52</minDewpointF>
<windSpeedKTS>2</windSpeedKTS>
<sunset>1665329491</sunset>
<solradWM2>4768</solradWM2>
<windSpeedKPH>4</windSpeedKPH>
<windGustMPH>22</windGustMPH>
<maxHumidity>86</maxHumidity>
<windSpeedMPH>2</windSpeedMPH>
<windGustKPH>36</windGustKPH>
<windDirMaxDEG>343</windDirMaxDEG>
<tempC>null</tempC>
</periods>
<periods>
<dateTimeISO>2022-10-10T07:00:00+02:00</dateTimeISO>
<windDirMin80m>E</windDirMin80m>
<windDirMin80mDEG>91</windDirMin80mDEG>
<feelslikeC>21</feelslikeC>
<visibilityMI>15</visibilityMI>
<windSpeedMaxMPH>9</windSpeedMaxMPH>
<windDirDEG>358</windDirDEG>
<windDir>N</windDir>
<sunriseISO>2022-10-10T05:53:40+02:00</sunriseISO>
<iceaccumMM>null</iceaccumMM>
<windSpeedMaxKTS>8</windSpeedMaxKTS>
<iceaccumIN>null</iceaccumIN>
<minTempF>70</minTempF>
<snowIN>0</snowIN>
<weather>Partly Cloudy</weather>
<sunsetISO>2022-10-10T17:30:21+02:00</sunsetISO>
<maxFeelslikeC>30</maxFeelslikeC>
<humidity>75</humidity>
<windDir80m>N</windDir80m>
<maxFeelslikeF>86</maxFeelslikeF>
<precipMM>0</precipMM>
<sky>64</sky>
<windGust80mMPH>22</windGust80mMPH>
<windSpeedMax80mMPH>22</windSpeedMax80mMPH>
<weatherPrimary>Partly Cloudy</weatherPrimary>
<windGust80mKPH>36</windGust80mKPH>
<avgDewpointF>58</avgDewpointF>
<windSpeedMax80mKPH>36</windSpeedMax80mKPH>
<windGust80mKTS>19</windGust80mKTS>
<avgDewpointC>14</avgDewpointC>
<precipIN>0</precipIN>
<windSpeedMax80mKTS>19</windSpeedMax80mKTS>
<windDirMinDEG>358</windDirMinDEG>
<windSpeedMaxKPH>15</windSpeedMaxKPH>
<windSpeedMin80mKTS>7</windSpeedMin80mKTS>
<feelslikeF>69</feelslikeF>
<validTime>2022-10-10T07:00:00+02:00</validTime>
<windSpeedMin80mMPH>8</windSpeedMin80mMPH>
<solradMaxWM2>597</solradMaxWM2>
<avgTempC>26</avgTempC>
<windSpeedMin80mKPH>13</windSpeedMin80mKPH>
<weatherPrimaryCoded>::SC</weatherPrimaryCoded>
<sunrise>1665374020</sunrise>
<avgTempF>78</avgTempF>
<windDirMin>N</windDirMin>
<maxCoverage/>
<icon>pcloudy.png</icon>
<minFeelslikeC>21</minFeelslikeC>
<dewpointC>16</dewpointC>
<cloudsCoded>SC</cloudsCoded>
<minFeelslikeF>69</minFeelslikeF>
<minHumidity>35</minHumidity>
<dewpointF>61</dewpointF>
<windSpeed80mKTS>7</windSpeed80mKTS>
<pop>0</pop>
<snowCM>0</snowCM>
<windDirMax>N</windDirMax>
<windSpeed80mMPH>8</windSpeed80mMPH>
<windSpeed80mKPH>13</windSpeed80mKPH>
<windDir80mDEG>8</windDir80mDEG>
<maxTempC>31</maxTempC>
<pressureMB>1017</pressureMB>
<visibilityKM>24.135</visibilityKM>
<timestamp>1665378000</timestamp>
<maxTempF>87</maxTempF>
<tempF>null</tempF>
<minDewpointC>13</minDewpointC>
<solradMinWM2>0</solradMinWM2>
<windSpeedMinKTS>2</windSpeedMinKTS>
<windDirMax80mDEG>10</windDirMax80mDEG>
<windGustKTS>16</windGustKTS>
<windSpeedMinKPH>4</windSpeedMinKPH>
<maxDewpointF>61</maxDewpointF>
<windSpeedMinMPH>2</windSpeedMinMPH>
<avgFeelslikeC>25</avgFeelslikeC>
<uvi>6</uvi>
<windDirMax80m>N</windDirMax80m>
<maxDewpointC>16</maxDewpointC>
<pressureIN>30.03</pressureIN>
<avgFeelslikeF>78</avgFeelslikeF>
<iceaccum>null</iceaccum>
<isDay>true</isDay>
<minTempC>21</minTempC>
<minDewpointF>55</minDewpointF>
<windSpeedKTS>2</windSpeedKTS>
<sunset>1665415821</sunset>
<solradWM2>4494</solradWM2>
<windSpeedKPH>4</windSpeedKPH>
<windGustMPH>19</windGustMPH>
<maxHumidity>75</maxHumidity>
<windSpeedMPH>2</windSpeedMPH>
<windGustKPH>30</windGustKPH>
<windDirMaxDEG>10</windDirMaxDEG>
<tempC>null</tempC>
</periods>
<periods>
<dateTimeISO>2022-10-11T07:00:00+02:00</dateTimeISO>
<windDirMin80m>NNE</windDirMin80m>
<windDirMin80mDEG>13</windDirMin80mDEG>
<feelslikeC>22</feelslikeC>
<visibilityMI>15</visibilityMI>
<windSpeedMaxMPH>18</windSpeedMaxMPH>
<windDirDEG>13</windDirDEG>
<windDir>NNE</windDir>
<sunriseISO>2022-10-11T05:54:18+02:00</sunriseISO>
<iceaccumMM>null</iceaccumMM>
<windSpeedMaxKTS>15</windSpeedMaxKTS>
<iceaccumIN>null</iceaccumIN>
<minTempF>70</minTempF>
<snowIN>0</snowIN>
<weather>Sunny</weather>
<sunsetISO>2022-10-11T17:29:13+02:00</sunsetISO>
<maxFeelslikeC>31</maxFeelslikeC>
<humidity>71</humidity>
<windDir80m>NNE</windDir80m>
<maxFeelslikeF>87</maxFeelslikeF>
<precipMM>0</precipMM>
<sky>0</sky>
<windGust80mMPH>19</windGust80mMPH>
<windSpeedMax80mMPH>19</windSpeedMax80mMPH>
<weatherPrimary>Sunny</weatherPrimary>
<windGust80mKPH>31</windGust80mKPH>
<avgDewpointF>55</avgDewpointF>
<windSpeedMax80mKPH>31</windSpeedMax80mKPH>
<windGust80mKTS>17</windGust80mKTS>
<avgDewpointC>13</avgDewpointC>
<precipIN>0</precipIN>
<windSpeedMax80mKTS>17</windSpeedMax80mKTS>
<windDirMinDEG>14</windDirMinDEG>
<windSpeedMaxKPH>28</windSpeedMaxKPH>
<windSpeedMin80mKTS>9</windSpeedMin80mKTS>
<feelslikeF>72</feelslikeF>
<validTime>2022-10-11T07:00:00+02:00</validTime>
<windSpeedMin80mMPH>11</windSpeedMin80mMPH>
<solradMaxWM2>758</solradMaxWM2>
<avgTempC>26</avgTempC>
<windSpeedMin80mKPH>18</windSpeedMin80mKPH>
<weatherPrimaryCoded>::CL</weatherPrimaryCoded>
<sunrise>1665460458</sunrise>
<avgTempF>78</avgTempF>
<windDirMin>NNE</windDirMin>
<maxCoverage/>
<icon>sunny.png</icon>
<minFeelslikeC>22</minFeelslikeC>
<dewpointC>17</dewpointC>
<cloudsCoded>CL</cloudsCoded>
<minFeelslikeF>72</minFeelslikeF>
<minHumidity>30</minHumidity>
<dewpointF>62</dewpointF>
<windSpeed80mKTS>10</windSpeed80mKTS>
<pop>0</pop>
<snowCM>0</snowCM>
<windDirMax>NNE</windDirMax>
<windSpeed80mMPH>12</windSpeed80mMPH>
<windSpeed80mKPH>19</windSpeed80mKPH>
<windDir80mDEG>16</windDir80mDEG>
<maxTempC>31</maxTempC>
<pressureMB>1015</pressureMB>
<visibilityKM>24.135</visibilityKM>
<timestamp>1665464400</timestamp>
<maxTempF>87</maxTempF>
<tempF>null</tempF>
<minDewpointC>11</minDewpointC>
<solradMinWM2>0</solradMinWM2>
<windSpeedMinKTS>7</windSpeedMinKTS>
<windDirMax80mDEG>28</windDirMax80mDEG>
<windGustKTS>15</windGustKTS>
<windSpeedMinKPH>14</windSpeedMinKPH>
<maxDewpointF>62</maxDewpointF>
<windSpeedMinMPH>8</windSpeedMinMPH>
<avgFeelslikeC>26</avgFeelslikeC>
<uvi>null</uvi>
<windDirMax80m>NNE</windDirMax80m>
<maxDewpointC>17</maxDewpointC>
<pressureIN>29.98</pressureIN>
<avgFeelslikeF>79</avgFeelslikeF>
<iceaccum>null</iceaccum>
<isDay>true</isDay>
<minTempC>21</minTempC>
<minDewpointF>51</minDewpointF>
<windSpeedKTS>8</windSpeedKTS>
<sunset>1665502153</sunset>
<solradWM2>5450</solradWM2>
<windSpeedKPH>15</windSpeedKPH>
<windGustMPH>17</windGustMPH>
<maxHumidity>71</maxHumidity>
<windSpeedMPH>9</windSpeedMPH>
<windGustKPH>28</windGustKPH>
<windDirMaxDEG>28</windDirMaxDEG>
<tempC>null</tempC>
</periods>
<periods>
<dateTimeISO>2022-10-12T07:00:00+02:00</dateTimeISO>
<windDirMin80m>NNE</windDirMin80m>
<windDirMin80mDEG>15</windDirMin80mDEG>
<feelslikeC>22</feelslikeC>
<visibilityMI>15</visibilityMI>
<windSpeedMaxMPH>16</windSpeedMaxMPH>
<windDirDEG>12</windDirDEG>
<windDir>NNE</windDir>
<sunriseISO>2022-10-12T05:54:55+02:00</sunriseISO>
<iceaccumMM>null</iceaccumMM>
<windSpeedMaxKTS>14</windSpeedMaxKTS>
<iceaccumIN>null</iceaccumIN>
<minTempF>69</minTempF>
<snowIN>0</snowIN>
<weather>Mostly Sunny</weather>
<sunsetISO>2022-10-12T17:28:04+02:00</sunsetISO>
<maxFeelslikeC>31</maxFeelslikeC>
<humidity>68</humidity>
<windDir80m>NNE</windDir80m>
<maxFeelslikeF>88</maxFeelslikeF>
<precipMM>0</precipMM>
<sky>27</sky>
<windGust80mMPH>21</windGust80mMPH>
<windSpeedMax80mMPH>21</windSpeedMax80mMPH>
<weatherPrimary>Mostly Sunny</weatherPrimary>
<windGust80mKPH>33</windGust80mKPH>
<avgDewpointF>55</avgDewpointF>
<windSpeedMax80mKPH>33</windSpeedMax80mKPH>
<windGust80mKTS>18</windGust80mKTS>
<avgDewpointC>13</avgDewpointC>
<precipIN>0</precipIN>
<windSpeedMax80mKTS>18</windSpeedMax80mKTS>
<windDirMinDEG>12</windDirMinDEG>
<windSpeedMaxKPH>26</windSpeedMaxKPH>
<windSpeedMin80mKTS>10</windSpeedMin80mKTS>
<feelslikeF>72</feelslikeF>
<validTime>2022-10-12T07:00:00+02:00</validTime>
<windSpeedMin80mMPH>11</windSpeedMin80mMPH>
<solradMaxWM2>743</solradMaxWM2>
<avgTempC>26</avgTempC>
<windSpeedMin80mKPH>18</windSpeedMin80mKPH>
<weatherPrimaryCoded>::FW</weatherPrimaryCoded>
<sunrise>1665546895</sunrise>
<avgTempF>79</avgTempF>
<windDirMin>NNE</windDirMin>
<maxCoverage/>
<icon>fair.png</icon>
<minFeelslikeC>22</minFeelslikeC>
<dewpointC>16</dewpointC>
<cloudsCoded>FW</cloudsCoded>
<minFeelslikeF>72</minFeelslikeF>
<minHumidity>29</minHumidity>
<dewpointF>60</dewpointF>
<windSpeed80mKTS>10</windSpeed80mKTS>
<pop>0</pop>
<snowCM>0</snowCM>
<windDirMax>E</windDirMax>
<windSpeed80mMPH>12</windSpeed80mMPH>
<windSpeed80mKPH>19</windSpeed80mKPH>
<windDir80mDEG>15</windDir80mDEG>
<maxTempC>31</maxTempC>
<pressureMB>1014</pressureMB>
<visibilityKM>24.135</visibilityKM>
<timestamp>1665550800</timestamp>
<maxTempF>88</maxTempF>
<tempF>null</tempF>
<minDewpointC>11</minDewpointC>
<solradMinWM2>0</solradMinWM2>
<windSpeedMinKTS>7</windSpeedMinKTS>
<windDirMax80mDEG>96</windDirMax80mDEG>
<windGustKTS>15</windGustKTS>
<windSpeedMinKPH>13</windSpeedMinKPH>
<maxDewpointF>60</maxDewpointF>
<windSpeedMinMPH>8</windSpeedMinMPH>
<avgFeelslikeC>26</avgFeelslikeC>
<uvi>null</uvi>
<windDirMax80m>E</windDirMax80m>
<maxDewpointC>16</maxDewpointC>
<pressureIN>29.95</pressureIN>
<avgFeelslikeF>80</avgFeelslikeF>
<iceaccum>null</iceaccum>
<isDay>true</isDay>
<minTempC>21</minTempC>
<minDewpointF>51</minDewpointF>
<windSpeedKTS>8</windSpeedKTS>
<sunset>1665588484</sunset>
<solradWM2>4740</solradWM2>
<windSpeedKPH>15</windSpeedKPH>
<windGustMPH>17</windGustMPH>
<maxHumidity>68</maxHumidity>
<windSpeedMPH>9</windSpeedMPH>
<windGustKPH>28</windGustKPH>
<windDirMaxDEG>96</windDirMaxDEG>
<tempC>null</tempC>
</periods>
<interval>day</interval>
<place>
<country>eg</country>
<name>cairo</name>
<state>qh</state>
</place>
</response>
<error>null</error>