我有一个 JSON 结构,其中一些对象可以有任意名称,我想规范化这个结构,使对象变得匿名,但可以通过“名称”属性识别。
从
{
{
"arbitrary_name": {
...
}
}
至
{
"name": "arbitrary_name",
...
}
第一步,我想向“任意名称”对象添加一个名称属性,然后在下一步中删除“任意名称”对象并将其属性向上移动一级。
首先,我正在查询指向对象的所有路径的 JSON 结构(使用https://github.com/json-path/JsonPath),这些路径需要规范化。它们都位于名为“children”的数组下。然后我迭代这个路径,获取对象的值并添加一个 name 属性。
我的方法在顶级对象上运行良好,但如果它们是嵌套的(子对象-> service.children[0].arbitrary_name1.children[0]),JsonPath 会引发异常,我不知道属性是什么失踪。我在这个结构中打印了所有可能的路径,并且也打印了查询的路径(导致异常)。
我的输入如下所示:
{
"service": {
"foo": "bar",
"children": [
{
"arbitrary_name1": {
"foo": "bar",
"children": [
{
"arbitrary_name_2": {
"foo": "bar"
}
}
]
}
}
]
}
}
我的代码:
final File src = Files.readString(xxx); // Path to file with JSON content
final Configuration c = Configuration.defaultConfiguration().setOptions(Option.ALWAYS_RETURN_LIST, Option.AS_PATH_LIST);
final DocumentContext pathsContext = JsonPath.parse(src, c);
final DocumentContext valuesContext = JsonPath.parse(src);
final Collection<String> pathsToObjects = pathsContext.read("$..children[*]");
/* prints:
$['service']['children'][0]
$['service']['children'][0]['arbitrary_name1']['children'][0]
*/
for (String jsonPath : pathsToObjects) {
Map<String, Map> valuesOfOuterObject = valuesContext.read(jsonPath); // Exception on 2nd path
String name = valuesOfOuterObject.keySet().stream().findFirst().get();
final Map<String, Object> valuesOfInnerObject = valuesOfOuterObject.get(name);
valuesOfInnerObject.put("name", name);
valuesContext.set(jsonPath, valuesOfInnerObject);
}
相应的异常说:
com.jayway.jsonpath.PathNotFoundException: Missing property in path $['service']['children'][0]['arbitrary_name1']
我错过了什么还是有更简单的方法?