Json-den-java is a library that parses (Decodes), stringifies (ENcodes) and manipulates JSON.
Its distinctive features include
equals
checks the value equality (not the reference equality).
clone
deeply copies JSON values.
diff
identifies different parts of two JSON values.
These and the following methods properly handle hierarchical structure of JSON values.getx
which can query JSON nodes
located deep in hierarchical structures with a single path.
For example, you can use json.getx("how.deep.is.your.love")
instead of json.get("how").get("deep").get("is").get("your").get("love")
.setx
which creates parent nodes as needed,
like the UNIX shell command mkdir -p
, and then updates the JSON node at the specified path.
For example, json.setx("how.deep.is.your.love", "10,000ft")
sets “10,000ft”
at “how.deep.is.your.love”
even when the node corresponding to ‘how’, ‘deep’, ‘is’ or ‘your’ is currently absent.intersect
, subtract
and merge
on JSON objects and arrays.For more information, download the source code, run gen-apidocs.sh
included,
and see the generated API documentation.
Json-den-java is under BSD-2 license.
Following are code snippets in io.github.hyunikn.jsonden.example.Example class and their console
outputs when run.
You can run mvn exec:java -Dexec.mainClass=io.github.hyunikn.jsonden.example.Example
in the
project root directory to get the outputs.
left.json | right.json | |
---|---|---|
```javascript /** comment preserved */ /* comment dropped */ // comment dropped too { /** left only */ "l": {}, /** common */ "c": 7, /** different */ "d": true, "o": { "l": "left", /** this goes to c, not l */ "c": [ true, false ], "d": 1.1, "d2": [ false, true ] }, "a": [ { "l": { "L": "L" }, "c": { "C": null }, "d": { "D": "O" } }, [ 1, 2, 3 ], [ 10, 20, 30 ] ] } ``` | ```javascript { "r": [], "c": 7, "d": false, "o": { "r": "right", "c": [ true, false ], "d": 3.3, "d2": [ true, false ] }, "a": [ { "r": { "R": "R" }, "c": { "C": null }, "d": { "D": "X" } }, [ 1, 2, 3 ], [ 30, 20, 10, 0 ], { "r": "R" } ] } ``` |
Code:
package io.github.hyunikn.jsonden.example;
import io.github.hyunikn.jsonden.*;
import io.github.hyunikn.jsonden.exception.*;
...
...
public class Example {
public static void main(String[] argv) throws ParseError, UnreachablePath {
String leftText = readFile("left.json");
String rightText = readFile("right.json");
// parse
JsonObj left = JsonObj.parse(leftText);
JsonObj right = JsonObj.parse(rightText);
// stringify
System.out.println("# stringify with indent size 0");
System.out.println(left.stringify(0));
System.out.println("# stringify with indent size 2");
System.out.println(left.stringify(2));
Output:
# stringify with indent size 0
/** comment preserved */{/** left only */"l":{},/** common */"c":7,/** different */"d":true,"o":{"l":"left",/** this goes to c, not l */"c":[true,false],"d":1.1,"d2":[false,true]},"a":[{"l":{"L":"L"},"c":{"C":null},"d":{"D":"O"}},[1,2,3],[10,20,30]]}
# stringify with indent size 2
/** comment preserved */
{
/** left only */
"l": {},
/** common */
"c": 7,
/** different */
"d": true,
"o": {
"l": "left",
/** this goes to c, not l */
"c": [
true,
false
],
"d": 1.1,
"d2": [
false,
true
]
},
"a": [
{
"l": {
"L": "L"
},
"c": {
"C": null
},
"d": {
"D": "O"
}
},
[
1,
2,
3
],
[
10,
20,
30
]
]
}
Code:
// diff
System.out.print("# diff");
System.out.println(Jsons.prettyPrintDiff(left.diff(right)));
Output:
# diff
l:
L: {}
R: <none>
d:
L: true
R: false
o.l:
L: "left"
R: <none>
o.d:
L: 1.1
R: 3.3
o.d2.#0:
L: false
R: true
o.d2.#1:
L: true
R: false
a.#0.l.L:
L: "L"
R: <none>
a.#0.d.D:
L: "O"
R: "X"
a.#2.#0:
L: 10
R: 30
a.#2.#2:
L: 30
R: 10
r:
L: <none>
R: []
o.r:
L: <none>
R: "right"
a.#0.r.R:
L: <none>
R: "R"
a.#2.#3:
L: <none>
R: 0
a.#3.r:
L: <none>
R: "R"
Code:
// intersect, subtract and merge
System.out.println("# intersect");
System.out.println(Jsons.intersect(left, right).stringify(StrOpt.VALUES_ONLY));
System.out.println("# subtract");
System.out.println(Jsons.subtract(left, right).stringify(StrOpt.VALUES_ONLY));
System.out.println("# merge");
System.out.println(Jsons.merge(left, right).stringify(StrOpt.VALUES_ONLY));
Output:
# intersect
{
"c": 7,
"o": {
"c": [
true,
false
]
},
"a": [
{
"c": {
"C": null
}
},
[
1,
2,
3
],
[
null,
20
]
]
}
# subtract
{
"l": {},
"d": true,
"o": {
"l": "left",
"d": 1.1,
"d2": [
false,
true
]
},
"a": [
{
"l": {
"L": "L"
},
"d": {
"D": "O"
}
},
null,
[
10,
null,
30
]
]
}
# merge
{
"l": {},
"c": 7,
"d": false,
"o": {
"l": "left",
"c": [
true,
false
],
"d": 3.3,
"d2": [
true,
false
],
"r": "right"
},
"a": [
{
"l": {
"L": "L"
},
"c": {
"C": null
},
"d": {
"D": "X"
},
"r": {
"R": "R"
}
},
[
1,
2,
3
],
[
30,
20,
10,
0
],
{
"r": "R"
}
],
"r": []
}
Code:
// flatten and loadFlattened
System.out.println("# flatten");
LinkedHashMap<String, Json> flattened = left.flatten();
System.out.println(Jsons.prettyPrintFlattened(flattened));
JsonObj restored = JsonObj.instance().loadFlattened(flattened);
if (left.equals(restored)) {
System.out.println("# the original and the restored are equal");
} else {
assert false;
}
Output:
# flatten
l: {}
c: 7
d: true
o.l: "left"
o.c.#0: true
o.c.#1: false
o.d: 1.1
o.d2.#0: false
o.d2.#1: true
a.#0.l.L: "L"
a.#0.c.C: null
a.#0.d.D: "O"
a.#1.#0: 1
a.#1.#1: 2
a.#1.#2: 3
a.#2.#0: 10
a.#2.#1: 20
a.#2.#2: 30
# the original and the restored are equal
You can get the latest stable version from Maven Central by adding the following dependency in your pom.xml:
<dependency>
<groupId>io.github.hyunikn</groupId>
<artifactId>jsonden</artifactId>
<version>0.9.7</version>
</dependency>