How to fetch all nodes from parent to child from JSON Object in java?

Devanshu :

For the given json object, I want to print all the nodes in the path from parent to child in java. For example, for the below given json as input:

{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    }
}}

Output is expected as:

widget.debug
widget.window.title
widget.window.name
.
.
widget.image.src
widget.image.name

I tried following code. I think I should remove a node once it is no more traversal but I am not sure how to do that and whether it is the solution.

public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
        String inputJson = "{\"widget\": {\"window\": {\"title\": \"Sample Konfabulator Widget\","
                + "\"name\": \"main_window\",\"width\": 500,\"height\": 500},\"image\": { \"src\": \"Images/Sun.png\","
                + "\"name\": \"sun1\",\"hOffset\": 250,\"vOffset\": 250,\"alignment\": \"center\"},\"text\": {"
                + "\"data\": \"Click Here\",\"size\": 36,\"style\": \"bold\",\"name\": \"text1\",\"hOffset\": 250,"
                + "\"vOffset\": 100,\"alignment\": \"center\",\"onMouseUp\": 20}}}";

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode rootNode = objectMapper.readTree(inputJson);
        StringBuilder sb = new StringBuilder();
        traverse(rootNode, sb);
    }

    private static void traverse(JsonNode node, StringBuilder sb) {
        if (node.getNodeType() == JsonNodeType.OBJECT) {
            traverseObject(node, sb);
        } else {
            throw new RuntimeException("Not yet implemented");
        }
    }

    private static void traverseObject(JsonNode node, StringBuilder sb) {
        node.fieldNames().forEachRemaining((String fieldName) -> {
            JsonNode childNode = node.get(fieldName);
            printNode(childNode, fieldName, sb);
            if (traversable(childNode)) {
                traverse(childNode, sb);
            }
        });
    }

    private static boolean traversable(JsonNode node) {
        return node.getNodeType() == JsonNodeType.OBJECT || node.getNodeType() == JsonNodeType.ARRAY;
    }

    private static void printNode(JsonNode node, String keyName, StringBuilder sb) {
        if (traversable(node)) {
            sb.append(keyName + ".");
            System.out.println(sb.toString());
        } else {
            sb.append(keyName + ".");
            System.out.println(sb.toString());
        }
    }

But getting output as:

widget.
widget.window.
widget.window.title.
widget.window.title.name.
widget.window.title.name.width.
widget.window.title.name.width.height.
widget.window.title.name.width.height.image.
widget.window.title.name.width.height.image.src.
widget.window.title.name.width.height.image.src.name.
widget.window.title.name.width.height.image.src.name.hOffset.
HoRn :

Currently you are using the same instance of StringBuilder, and text accumulates.

Rewrite the method, fork StringBuilders on each loop iteration:

    private static void traverseObject(JsonNode node, StringBuilder sb) {

        node.fieldNames().forEachRemaining((String fieldName) -> {
            StringBuilder sb2 = new StringBuilder(sb);
            JsonNode childNode = node.get(fieldName);
            printNode(childNode, fieldName, sb2);
            if (traversable(childNode)) {
                traverse(childNode, sb2);
            }
        });
    }

This gave me the desired result:

widget.
widget.debug.
widget.window.
widget.window.title.
widget.window.name.
widget.window.width.
widget.window.height.
widget.image.
widget.image.src.
widget.image.name.
widget.image.hOffset.
widget.image.vOffset.
widget.image.alignment.

Now, to get rid of points at the ends, just don't add point here:

    private static void printNode(JsonNode node, String keyName, StringBuilder sb) {
        if (traversable(node)) {
            sb.append(keyName + ".");
            System.out.println(sb.toString());
        } else {
            sb.append(keyName); // don't add point
            System.out.println(sb.toString());
        }
    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=25271&siteId=1