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

sjo*_*999 2 java json jackson

嗨,我使用 Jackson 用 Ja​​va 编写了一个 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"]}
Run Code Online (Sandbox Code Playgroud)

此 JSON 中的路径示例是:

/product/industry
Run Code Online (Sandbox Code Playgroud)

这将具有作为价值

"Real Estate"
Run Code Online (Sandbox Code Playgroud)

我编写的解析器获取所有直接包含值(而不是另一个 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());          
    }
}
Run Code Online (Sandbox Code Playgroud)

代码可以像这样运行:

processJson(ExampleJSON);
Run Code Online (Sandbox Code Playgroud)

结果给出:

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
Run Code Online (Sandbox Code Playgroud)

现在,对于这些中的每一个,我想获取 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
Run Code Online (Sandbox Code Playgroud)

等等....

The*_*tar 6

我这样做的方法是向递归方法 processNode 添加另一个参数,该参数将表示当前路径。

private void processNode(JsonNode n, String currentPath)
Run Code Online (Sandbox Code Playgroud)

每次深入递归时,调用带有附加了要进入的键的 currentPath 的方法。

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

所以在打印部分你会有:

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

System.out.println("Key: " + this.lastKey + " Value: " + n.asText() + " Path: " + currentPath);
Run Code Online (Sandbox Code Playgroud)