简体   繁体   English

java - 如何从Java中的JSON对象获取从父节点到子节点的所有节点?

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

For the given json object, I want to print all the nodes in the path from parent to child in java.对于给定的json对象,我想在java中打印从父到子路径中的所有节点。 For example, for the below given json as input:例如,对于下面给定的 json 作为输入:

{"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.

Currently, you are using the same instance of StringBuilder , and text accumulates.当前,您使用的是StringBuilder的相同实例,并且文本会累积。

Rewrite the method - fork StringBuilders on each loop iteration:重写方法 - 在每次循环迭代中 fork StringBuilders:

    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 periods at the end of the lines, just don't add period 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());
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM