嗨,我使用 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"]}
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)
等等....
我这样做的方法是向递归方法 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)