Как извлечь все узлы из родительского в дочерний из JSON объекта в java? - PullRequest
1 голос
/ 04 марта 2020

Для данного объекта json я хочу напечатать все узлы на пути от родителя к потомку в java. Например, для приведенного ниже 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"
    }
}}

Выход ожидается как:

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

Я попробовал следующий код. Я думаю, что я должен удалить узел, как только он перестанет проходить, но я не уверен, как это сделать и является ли это решением.

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());
        }
    }

Но получить вывод как:

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.

1 Ответ

2 голосов
/ 04 марта 2020

В настоящее время вы используете один и тот же экземпляр StringBuilder, и текст накапливается.

Перепишите метод - форк StringBuilders на каждой итерации l oop:

    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 дал мне желаемый результат:

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.

Теперь, чтобы избавиться от периодов в конце строк, просто не добавляйте период здесь:

    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());
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...