JSON:
[{"id":141741,"name":"Group","nodeTypeId":3,"deleted":false,"hasNodeAccesses":false,"children": [{"id":141742,"name":"Division","nodeTypeId":14,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141743,"name":"Site 1","nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141746,"name":"Converting","nodeTypeId":5,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141744,"name":"Site 2","nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141748,"name":"Converting","nodeTypeId":5,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141745,"name":"Site 3","nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141750,"name":"Converting","nodeTypeId":5,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141752,"name":"ML1","nodeTypeId":12,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141755,"nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141753,"name":"ML2","nodeTypeId":12,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141756,"nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[]}]},{"id":141754,"name":"ML3","nodeTypeId":12,"deleted":false,"hasNodeAccesses":false,"children":[{"id":141757,"nodeTypeId":4,"deleted":false,"hasNodeAccesses":false,"children":[]}]}]}]}]
Code:
public List<String> getCapexStrategyNodeNames() {
JsonNode capexStrategyNodeList = client.getCapexStrategyNodes();
JSONArray nodes = capexStrategyNodeList.getArray();
List<JSONObject> nodeList = nodes.toList();
return retrieveValues(nodeList, "name");
}
private List<String> retrieveValues(List<JSONObject> list, String key) {
return list.stream()
.map(val -> val.getString(key))
.collect(Collectors.toList());
}
Output:
[Group]
I'm only retrieving the first value
How do I retrieve all name values from a nested JSON Array?
Thanks in advance!
With your current implementation, you are getting JsonNode object and you are reading it's name property, but you are not reading that property for it's chlildren (inner objects).
You have to query all nested objects recursivly and get a value of field name.
In my opinion the simplest way achieve this is by using JsonPath.
Add this dependency in pom.xml file:
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.4.0</version>
</dependency>
And here is the code snippet:
public static void main(String[] args) throws JsonProcessingException {
String json = "[{\"id\":141741,\"name\":\"Group\",\"nodeTypeId\":3,\"deleted\":false,\"hasNodeAccesses\":false,\"children\": [{\"id\":141742,\"name\":\"Division\",\"nodeTypeId\":14,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141743,\"name\":\"Site 1\",\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141746,\"name\":\"Converting\",\"nodeTypeId\":5,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141744,\"name\":\"Site 2\",\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141748,\"name\":\"Converting\",\"nodeTypeId\":5,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141745,\"name\":\"Site 3\",\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141750,\"name\":\"Converting\",\"nodeTypeId\":5,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141752,\"name\":\"ML1\",\"nodeTypeId\":12,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141755,\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141753,\"name\":\"ML2\",\"nodeTypeId\":12,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141756,\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141754,\"name\":\"ML3\",\"nodeTypeId\":12,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141757,\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]}]}]}]";
List<Object> names= JsonPath.parse(json)
.read("$..name"); //Recursive descent: Searches for the/specified property name recursively and returns an array of all values with this property name. Always returns a list, even if just one property is found.
System.out.println(names);
}
If you run this code you will see output like this:
["Group","Division","Site 1","Converting","Site 2","Converting","Site 3","Converting","ML1","ML2","ML3"]
Your json has only one object, so it is correct that your output has just one item.
This is the only object present in the array at first level
[{
"id": 141741,
"name": "Group",
"nodeTypeId": 3,
"deleted": false,
"hasNodeAccesses": false,
"children": [...]
}]
So your code should return ["Group"] and it is correct.
Probably you need to navigate through the children and maybe recursively to any nested children. In this case you need to change the algorithm
Library Josson also has the capability. The output is an ArrayNode.
https://github.com/octomix/josson
Josson josson = Josson.fromJsonString("[{\"id\":141741,\"name\":\"Group\",\"nodeTypeId\":3,\"deleted\":false,\"hasNodeAccesses\":false,\"children\": [{\"id\":141742,\"name\":\"Division\",\"nodeTypeId\":14,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141743,\"name\":\"Site 1\",\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141746,\"name\":\"Converting\",\"nodeTypeId\":5,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141744,\"name\":\"Site 2\",\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141748,\"name\":\"Converting\",\"nodeTypeId\":5,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141745,\"name\":\"Site 3\",\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141750,\"name\":\"Converting\",\"nodeTypeId\":5,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141752,\"name\":\"ML1\",\"nodeTypeId\":12,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141755,\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141753,\"name\":\"ML2\",\"nodeTypeId\":12,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141756,\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]},{\"id\":141754,\"name\":\"ML3\",\"nodeTypeId\":12,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[{\"id\":141757,\"nodeTypeId\":4,\"deleted\":false,\"hasNodeAccesses\":false,\"children\":[]}]}]}]}]");
JsonNode node = josson.getNode("cumulateCollect(name, children)");
System.out.println(node.toPrettyString());
Output
[ "Group", "Division", "Site 1", "Converting", "Site 2", "Converting", "Site 3", "Converting", "ML1", "ML2", "ML3" ]
I have a json like this:
[
[
"Passport Number",
"NATIONALITY",
"REASONS"
],
[
"SHAIS100",
"INDIA",
""
],
[
"",
"",
"Agent ID is not matched."
],
[
"",
"",
""
]
]
I want to populate this to ArrayList<String[]>,Please tell me how to do?
And empty strings should not convert as null.
That's very simple, you just need to do the following:
1.- First create the Gson object:
Gson gson = new Gson();
2.- Then get the correspondent Type for your List<String[]> (Note that you can't do something like List<String[]>.class due to Java's type erasure):
Type type = new TypeToken<List<String[]>>() {}.getType();
3.- Finally parse the JSON into a structure of type type:
List<String[]> yourList = gson.fromJson(yourJsonString, type);
Take a look at Gson docs
Gson gson = new Gson();
int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};
(Serialization)
gson.toJson(ints); ==> prints [1,2,3,4,5]
gson.toJson(strings); ==> prints ["abc", "def", "ghi"]
(Deserialization)
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class);
==> ints2 will be same as ints
Tis is important for you: We also support multi-dimensional arrays, with arbitrarily complex element types
For null objects, Gson by default will not convert as null. Ref.
But you can configure to scan those nulls attributes if you want to do it after.
The default behaviour that is implemented in Gson is that null object fields are ignored. This allows for a more compact output format; however, the client must define a default value for these fields as the JSON format is converted back into its Java.
Here's how you would configure a Gson instance to output null:
Gson gson = new GsonBuilder().serializeNulls().create();
In your problem maybe you don't need to configure that.
I hope it helps.