一部のオブジェクトに任意の名前を付けることができる JSON 構造があり、この構造を正規化して、オブジェクトが匿名になるようにしますが、「名前」プロパティで識別できるようにします。
から
{
{
"arbitrary_name": {
...
}
}
に
{
"name": "arbitrary_name",
...
}
最初のステップでは、名前プロパティを「任意の名前」オブジェクトに追加し、次のステップで「任意の名前」オブジェクトを削除して、そのプロパティを 1 レベル上に移動します。
まず、正規化する必要があるオブジェクトを指すすべてのパスについて、 ( https://github.com/json-path/JsonPathを使用して) JSON 構造を照会しています。それらはすべて、「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']
私は何が欠けていますか、またはより簡単なアプローチがありますか?