How to iterate all subnodes of a json object?

You can convert JSON object to HashMap so you will get key and value pairs

here i use GSON library

code snippet

Gson gson = new Gson();
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String,String> map = gson.fromJson(json, type);

so you can iterate this map for your purpose.


elements() gives you an iterator for subnodes and fields() gives you the properties.

With that, you can code a recursive function that walks through all nodes.


Here is working sample, input is String

public static void main(String[] args) throws IOException {
    JsonNode node = om.readTree(input);
    LOG.info(node.toString());
    process("", node);
}

private static void process(String prefix, JsonNode currentNode) {
    if (currentNode.isArray()) {
        ArrayNode arrayNode = (ArrayNode) currentNode;
        Iterator<JsonNode> node = arrayNode.elements();
        int index = 1;
        while (node.hasNext()) {
            process(!prefix.isEmpty() ? prefix + "-" + index : String.valueOf(index), node.next());
            index += 1;
        }
    }
    else if (currentNode.isObject()) {
        currentNode.fields().forEachRemaining(entry -> process(!prefix.isEmpty() ? prefix + "-" + entry.getKey() : entry.getKey(), entry.getValue()));
    }
    else {
        LOG.info(prefix + ": " + currentNode.toString());
    }
}

This will work for you :

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);
Map<String, String> map = new HashMap<>();
addKeys("", root, map, new ArrayList<>());

map.entrySet()
     .forEach(System.out::println);

private void addKeys(String currentPath, JsonNode jsonNode, Map<String, String> map, List<Integer> suffix) {
    if (jsonNode.isObject()) {
        ObjectNode objectNode = (ObjectNode) jsonNode;
        Iterator<Map.Entry<String, JsonNode>> iter = objectNode.fields();
        String pathPrefix = currentPath.isEmpty() ? "" : currentPath + "-";

        while (iter.hasNext()) {
            Map.Entry<String, JsonNode> entry = iter.next();
            addKeys(pathPrefix + entry.getKey(), entry.getValue(), map, suffix);
        }
    } else if (jsonNode.isArray()) {
        ArrayNode arrayNode = (ArrayNode) jsonNode;

        for (int i = 0; i < arrayNode.size(); i++) {
            suffix.add(i + 1);
            addKeys(currentPath, arrayNode.get(i), map, suffix);

            if (i + 1 <arrayNode.size()){
                suffix.remove(arrayNode.size() - 1);
            }
        }

    } else if (jsonNode.isValueNode()) {
        if (currentPath.contains("-")) {
            for (int i = 0; i < suffix.size(); i++) {
                currentPath += "-" + suffix.get(i);
            }

            suffix = new ArrayList<>();
        }

        ValueNode valueNode = (ValueNode) jsonNode;
        map.put(currentPath, valueNode.asText());
    }
}

For the json you gave the output will be :

name-items-name-1-2=2nditem
name-items-name-1-1=firstitem
name-items-stock-1-1=12
name-first-1=John
name-items-stock-1-2=23
company=John Company
name-last-1=Doe

Tags:

Java

Json

Jackson