Home > Enterprise >  Get values by key from JSON Multi-dimensional Array
Get values by key from JSON Multi-dimensional Array

Time:07-08

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!

CodePudding user response:

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

CodePudding user response:

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"]
  • Related