如何遍历一个json对象的所有子节点?

新手上路,请多包涵

我想遍历一个json对象的所有节点,写出一个普通的key-value map,如下:

 {
    "name": [
        {
            "first": "John",
            "last": "Doe",
        "items": [
            {
                "name": "firstitem",
                "stock": 12
            },
            {
                "name": "2nditem",
                "stock:" 23
            }
        ]
        }],
    "company": "John Company"
}

应该导致:

 name-first-1=John
name-last-1=Doe
name-items-name-1-1=firstitem (meaning the list index is always appended at the end of the name)
name-items-name-1-2=2nditem
company=John Company

这是获取 json 字符串作为 json 对象的方法:

 ObjectMapper mapper = new ObjectMapper(); //using jackson
JsonNode root = mapper.readTree(json);
//TODO how loop all nodes and subnodes, and always get their key + value?

但是我现在如何遍历所有节点并提取它们的密钥和内容呢?

原文由 membersound 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.9k
2 个回答

这对你有用:

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

对于 json 你给出的输出将是:

 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

原文由 Daniel Taub 发布,翻译遵循 CC BY-SA 3.0 许可协议

elements() 为您提供子节点的迭代器,而 fields() 为您提供属性。

这样,您就可以编写遍历所有节点的递归函数。

原文由 Thomas Weller 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题