#arrays #json #java-8 #jsonpath
Вопрос:
У меня есть Json, который содержит много узлов, и некоторые из узлов содержат массивы размером больше 1. Я пытаюсь написать некоторый код, чтобы уменьшить размеры массива до 1 и убедиться, что все атрибуты всех элементов массива включены в этот элемент массива. Затем я бы использовал «очищенный» json для создания схемы avro для использования с API потоковой передачи кафки. Фактические json очень большие, поэтому, чтобы сделать это управляемым, я пытаюсь это сделать.
Приведенный ниже код опробован с использованием gson, но у меня нет предпочтения в любом случае gson или Джексону.
Это моя попытка сделать это
private static void traverseJsonObject(JsonObject source, JsonObject compactedJson, String[] currentJsonPath) {
String parentKey = currentJsonPath[0];
source.keySet().forEach(key ->
{
Object keyValue = source.get(key);
if (keyValue instanceof JsonObject) {
currentJsonPath[0] = "." key;
traverseJsonObject((JsonObject) keyValue, compactedJson, currentJsonPath);
}
if (keyValue instanceof JsonArray) {
JsonArray srcArray = (JsonArray) keyValue;
// get the size of the array
// if the array size is 0 or 1
// continue
// if array size is > 1
// call compactArray method, passing the value ( jsonarray )
// this method should return an array of size 1
// remove the node from compactedJson
// add the returned array to compactedJson
if(srcArray.size() > 1) {
JsonObject firstArrayElement = (JsonObject) srcArray.get(0);
JsonArray merged = compactArray(srcArray, firstArrayElement);
//*********** **This is where my error occurs**
// I would ideally like to build a jsonpath for the key at this point,
// but I am NOT able to build a correct jsonpath here
JsonElement elementAtKey = compactedJson.get(key);
JsonArray compactedArrayAtKey = (JsonArray) compactedJson.get(key);
int srcArraySize = srcArray.size();
for (int i = 0; i < srcArraySize; i ) {
compactedArrayAtKey.remove(i);
}
compactedArrayAtKey.addAll(merged);
compactedJson.add(key, compactedArrayAtKey);
} //remove the key node
// add jsonarray at key
}
// iterate over keys of input json
// If the value for the key is of type jsonarray
// get the size of the array
// if the array size is 0 or 1
// continue
// if array size is > 1
// call compactArray method, passing the value ( jsonarray )
// this method should return an array of size 1
// remove the node from compactedJson
// add the returned array to compactedJson
});
}
private static JsonArray compactArray(JsonArray multiDimArray, JsonObject firstArrayElement) {
IntStream.range(0, multiDimArray.size()).forEach(index -> {
JsonElement srcElem = multiDimArray.get(index);
JsonObject srcAtIndex = (JsonObject) srcElem;
Set<String> sourceKeySet = srcAtIndex.keySet();
for (String key : srcAtIndex.keySet()) {
if(!firstArrayElement.has(key)) {
firstArrayElement.addProperty(key, String.valueOf(srcAtIndex.get(key)));
}
}
});
JsonArray oneElementArray = new JsonArray();
oneElementArray.add(firstArrayElement);
return oneElementArray;
}
Вот где возникает моя ошибка
JsonElement elementAtKey = compactedJson.get(key);
Пример JSON
{
"TopmostNode" {
"Level1-1"{
"level2-1" {
"attr2-1-1": "value2-2-1",
},
"level2-2" {
"attr2-2-1": "value2-2-1",
"level3-1": [
{
"attr3-1-1-1": "value3-1-1-1"
"attr3-1-1-2": "value3-1-1-2"
},
{
"attr3-1-1-1": "value3-1-1-1"
"attr3-1-2-1": "value3-1-2-1"
}
]
}
}
}
}
Expected Output
{
"TopmostNode" {
"Level1-1"{
"level2-1" {
"attr2-1-1": "value2-2-1",
},
"level2-2" {
"attr2-2-1": "value2-2-1",
"level3-1": [
{
"attr3-1-1-1": "value3-1-1-1"
"attr3-1-1-2": "value3-1-1-2"
"attr3-1-2-1": "value3-1-2-1"
}
]
}
}
}
}
I would ideally like to build a jsonpath for the key at this point, but I am NOT able to build a correct jsonpath here
Как я могу построить jsonpath при обходе объекта json ИЛИ
Есть ли другой подход, чтобы обрезать все массивы до размера 1?
Спасибо