Java:查找JSON对象中每个属性的确切路径

时间:2017-08-17 15:44:55

标签: java json jackson

您好我使用Jackson在Java中编写了一个JSON树解析器。现在我想找到JSON中每个属性的路径。示例JSON:

{"product":{
    "name":"Flipper",
    "industry":"Real Estate",
    "description":"Discovers correlations and trending criteria.",
    "someArray": ["bla1", "bla2", "bla3"],
    "productspecs":{"spec1":"somespec1",
                      "spec2":"someotherspec2"},
    "arrayOfObjects":[{"test1": "a1", "test2":"a2"},
                        {"Hi1": "b1", "Hi2":"b2"}]
},
"name":"Peter",
"anotherArray":["la1", "la2"]}

此JSON中的路径示例为:

/product/industry

将具有值

"Real Estate"

我编写的解析器获取直接包含值的所有属性(不是另一个JSON对象)。这是代码:

public void processJson(String jsonStr) {
    ObjectMapper objectMapper = new ObjectMapper();

    try {
        JsonNode node = objectMapper.readTree(jsonStr);  
        first = true;
        processNode(node);

    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

private void processNode(JsonNode n) {  
    if (n.isContainerNode()) {
        if (n.isArray()){
            Iterator<JsonNode> itt = n.iterator();
            while (itt.hasNext()) {
                JsonNode innerNode = itt.next();
                processNode(innerNode);
            }
        }
        else {
            Iterator<Map.Entry<String,JsonNode>> fieldsIterator = n.fields();
            Map.Entry<String,JsonNode> field;               
            while (fieldsIterator.hasNext()){
                field = fieldsIterator.next();
                this.lastKey = field.getKey();      
                location += "/" + this.lastKey;
                processNode(field.getValue());
            }
        }       
    }
    else if (n.isNull()) {
        propertyCount++;
        System.out.println("Key: " + this.lastKey + " Value: " + n);
    } else {
        propertyCount++;
        location = location.substring(0,location.lastIndexOf("/"));

        System.out.println("Key: " + this.lastKey  + " Value: " + n.asText());          
    }
}

代码可以像:

一样运行
processJson(ExampleJSON);

并给出结果:

Key: name Value: Flipper
Key: industry Value: Real Estate
Key: description Value: Discovers correlations and trending criteria.
Key: someArray Value: bla1
Key: someArray Value: bla2
Key: someArray Value: bla3
Key: spec1 Value: somespec1
Key: spec2 Value: someotherspec2
Key: test1 Value: a1
Key: test2 Value: a2
Key: Hi1 Value: b1
Key: Hi2 Value: b2
Key: name Value: Peter
Key: anotherArray Value: la1
Key: anotherArray Value: la2

现在,对于其中的每一个,我想获得JSON中的路径。所以:

Key: name Value: Flipper Path: product/name
Key: industry Value: Real Estate Path: product/industry
Key: description Value: Discovers correlations and trending criteria. Path: product/description
Key: someArray Value: bla1 Path: product/someArray
Key: someArray Value: bla2 Path: product/someArray
Key: someArray Value: bla3 Path: product/someArray

依旧......

2 个答案:

答案 0 :(得分:3)

我这样做的方法是在你的递归方法processNode中添加另一个参数,它代表当前路径。

private void processNode(JsonNode n, String currentPath)

每次进行更深入的递归时,请使用currentPath附加您要进入的键调用该方法。

while (fieldsIterator.hasNext()) {
    field = fieldsIterator.next();
    this.lastKey = field.getKey();
    location += "/" + this.lastKey;
    processNode(field.getValue(), currentPath + "/" + this.lastKey);
}       

所以在打印部分你会得到:

propertyCount++;
location = location.substring(0, location.lastIndexOf("/"));

System.out.println("Key: " + this.lastKey + " Value: " + n.asText() + " Path: " + currentPath);

答案 1 :(得分:0)

如果需要打印emptyNode的key、value、path,例如

{"emptyNode": {}}

然后添加

 else if(n.isEmpty()){
            System.out.println("Key: " + this.lastKey + " Value: " + n.asText() + " Path: " + path);
        }