I am witing a user interface in Java that allows the enduser to navigate in a JSON using Jayway JsonPath.
So given the example below
{
"people": [
{
"id": 1,
"fname": "Henry",
"lname": "Cavendish",
"profession": "scientist",
"research": [
{
"area": "Chemistry",
"years": [
{
"year": 1766
},
{
"year": 1781
}
]
},
{
"area": "Density of the Earth",
"years": [
{
"year": 1797
}
]
},
{
"area": "Electricity",
"years": [
{
"year": 1771
},
{
"year": 1781
}
]
}
]
},
{
"id": 1,
"fname": "Isaac",
"lname": "Newton",
"profession": "scientist",
"research": [
{
"area": "Calculus",
"years": [
{
"year": 1666
},
{
"year": 1669
}
]
},
{
"area": "Optics",
"years": [
{
"year": 1666
},
{
"year": 1675
}
]
},
{
"area": "Gravity",
"years": [
{
"year": 1679
},
{
"year": 1712
}
]
}
]
}
]
}
the user can for example use
$.people[*].research[*].years[*].year
to query all years. This is demonstrated with the following Java code
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import com.jayway.jsonpath.JsonPath;
public class PathTest {
public static void main(String[] args) throws IOException {
byte[] bytes = Files
.readAllBytes(Paths.get("test.json"));
String json = new String(bytes, StandardCharsets.UTF_8);
JsonPath path = JsonPath.compile("$.people[*].research[*].years[*].year");
List<Integer> yearList = path.read(json);
for (Integer year : yearList)
System.out.println(year);
}
}
which gives
1766
1781
1797
1771
1781
1666
1669
1666
1675
1679
1712
on execution. Now I would like to get the JsonPath of each node in the result like
1766 $.people[0].research[0].years[0].year
1781 $.people[0].research[0].years[1].year
1797 $.people[0].research[1].years[0].year
1771 $.people[0].research[2].years[0].year
1781 $.people[0].research[2].years[1].year
1666 $.people[1].research[0].years[0].year
1669 $.people[1].research[0].years[1].year
1666 $.people[1].research[1].years[0].year
1675 $.people[1].research[1].years[1].year
1679 $.people[1].research[2].years[0].year
1712 $.people[1].research[2].years[1].year
Is there any way to retrieve the path information for each of the nodes returned?
Thanks in advance!
You can use library Josson to do transformation and flatten the JSON.
https://github.com/octomix/josson
Deserialization
Josson josson = Josson.fromJsonString(
"{" +
" \"people\": [" +
" {" +
" \"id\": 1," +
" \"fname\": \"Henry\"," +
" \"lname\": \"Cavendish\"," +
" \"profession\": \"scientist\"," +
" \"research\": [" +
" {" +
" \"area\": \"Chemistry\"," +
" \"years\": [" +
" {" +
" \"year\": 1766" +
" }," +
" {" +
" \"year\": 1781" +
" }" +
" ]" +
" }," +
" {" +
" \"area\": \"Density of the Earth\"," +
" \"years\": [" +
" {" +
" \"year\": 1797" +
" }" +
" ]" +
" }," +
" {" +
" \"area\": \"Electricity\"," +
" \"years\": [" +
" {" +
" \"year\": 1771" +
" }," +
" {" +
" \"year\": 1781" +
" }" +
" ]" +
" }" +
" ]" +
" }," +
" {" +
" \"id\": 1," +
" \"fname\": \"Isaac\"," +
" \"lname\": \"Newton\"," +
" \"profession\": \"scientist\"," +
" \"research\": [" +
" {" +
" \"area\": \"Calculus\"," +
" \"years\": [" +
" {" +
" \"year\": 1666" +
" }," +
" {" +
" \"year\": 1669" +
" }" +
" ]" +
" }," +
" {" +
" \"area\": \"Optics\"," +
" \"years\": [" +
" {" +
" \"year\": 1666" +
" }," +
" {" +
" \"year\": 1675" +
" }" +
" ]" +
" }," +
" {" +
" \"area\": \"Gravity\"," +
" \"years\": [" +
" {" +
" \"year\": 1679" +
" }," +
" {" +
" \"year\": 1712" +
" }" +
" ]" +
" }" +
" ]" +
" }" +
" ]" +
"}");
Transformation
JsonNode node = josson.getNode(
"map(people.map(research.map(years.map(year)))).flatten('.','[%d]')");
System.out.println(node.toPrettyString());
System.out.println("------");
node.fields().forEachRemaining(entry ->
System.out.println("$." + entry.getKey() + " = " + entry.getValue().asText()));
Output
{
"people[0].research[0].years[0].year" : 1766,
"people[0].research[0].years[1].year" : 1781,
"people[0].research[1].years[0].year" : 1797,
"people[0].research[2].years[0].year" : 1771,
"people[0].research[2].years[1].year" : 1781,
"people[1].research[0].years[0].year" : 1666,
"people[1].research[0].years[1].year" : 1669,
"people[1].research[1].years[0].year" : 1666,
"people[1].research[1].years[1].year" : 1675,
"people[1].research[2].years[0].year" : 1679,
"people[1].research[2].years[1].year" : 1712
}
------
$.people[0].research[0].years[0].year = 1766
$.people[0].research[0].years[1].year = 1781
$.people[0].research[1].years[0].year = 1797
$.people[0].research[2].years[0].year = 1771
$.people[0].research[2].years[1].year = 1781
$.people[1].research[0].years[0].year = 1666
$.people[1].research[0].years[1].year = 1669
$.people[1].research[1].years[0].year = 1666
$.people[1].research[1].years[1].year = 1675
$.people[1].research[2].years[0].year = 1679
$.people[1].research[2].years[1].year = 1712