Can someone please help with Jolt transformation taking the following into consideration
Input:
{
"person": "Adam",
"personTitle": "MR",
"children": [
{
"name": "John",
"title": "MR",
"children": [
{
"name": "Sarah",
"title": "MR",
"children": [
]
}
]
},
{
"name": "Jimmy",
"title": "MR",
"children": [
{
"name": "Stephen",
"title": "MR",
"children": [
]
}
]
}
]
}
Output:
{
"person": "Adam",
"personTitle": "MR",
"children": [
{
"childname": "John",
"childtitle": "MR",
"children": [
{
"childname": "Sarah",
"childtitle": "MR",
"children": [
]
}
]
},
{
"childname": "Jimmy",
"childtitle": "MR",
"children": [
{
"childname": "Stephen",
"childtitle": "MR"
}
]
}
]
}
It's not possible to do unlimited deep exploration with Jolt. I see two solutions: (1) set a sufficiently but limited depth with the jolt specification or (2) use the recursivity of a programming language (without jolt).
For solution 2, I solved a problem this way:
package kapia.gbo.JsonProcessing;
import java.util.function.Function;
public interface JsonProcessing<T,R> {
/**
* In the {@code json}, rename all {@code key} attributes to {@code newKey} then apply the {@code function} with the
* old value linked to {@code key} as input and returns the new value linked to {@code newKey}.
*
* @param json to transform
* @param key to search and delete
* @param newKey to insert with the value returning by {@code function}
* @param function with {@code T} the type of old value {@code R} the type of new value
* @return json as String after transformation
*/
public String apply(String json, String key, String newKey, Function<T,R> function);
}
package kapia.gbo.JsonProcessing;
import java.util.function.Function;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class JsonProcessingWithGsonImpl implements kapia.gbo.JsonProcessing.JsonProcessing<JsonElement,JsonElement> {
public JsonProcessingWithGsonImpl() {
}
public String apply(String json, String key, String newKey, Function<JsonElement, JsonElement> function) {
JsonElement jsonElement = JsonParser.parseString(json).getAsJsonObject();
if (jsonElement.isJsonObject()) {
apply((JsonObject) jsonElement, key, newKey, (Function<JsonElement, JsonElement>) function);
}
return jsonElement.toString();
}
private void apply(JsonObject jsonObject, String key, String newKey,
Function<JsonElement, JsonElement> function) {
if (jsonObject.has(key)) {
JsonElement value = jsonObject.get(key);
jsonObject.remove(key);
jsonObject.add(newKey, function.apply(value));
}
// recursive exploration
for (String currentKey : jsonObject.keySet()) {
JsonElement element = jsonObject.get(currentKey);
if (element.isJsonObject()) {
apply((JsonObject) element, key, newKey, function);
} else if (element.isJsonArray()) {
apply((JsonArray) element, key, newKey, function);
}
}
}
private void apply(JsonArray jsonArray, String key, String newKey,
Function<JsonElement, JsonElement> function) {
for (JsonElement element : jsonArray) {
if (element.isJsonObject()) {
apply((JsonObject) element, key, newKey, function);
} else if (element.isJsonArray()) {
apply((JsonArray) element, key, newKey, function);
}
}
}
}
Test :
package kapia.gbo.JsonProcessing;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Map;
import java.util.function.Function;
import org.json.JSONException;
import org.junit.jupiter.api.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
public class AppTest {
private JsonProcessing<JsonElement, JsonElement> jsonParser = new JsonProcessingWithGsonImpl();
private final String JSON_03_INPUT = """
{
"policies": {
"insured": [
{
"addressType": 6,
"partyRef": "REF01",
"partyOrder": 1
},
{
"addressType": 6,
"partyRef": "REF02",
"partyOrder": 2
}
],
"subscribers": [
{
"addressType": 6,
"partyRef": "REF01",
"partyOrder": 1
}
]
}
}
""";
private final String JSON_03_EXPECTED = "{\"policies\":{\"insured\":[{\"addressType\":6,\"partyId\":1,\"partyOrder\":1},{\"addressType\":6,\"partyId\":2,\"partyOrder\":2}],\"subscribers\":[{\"addressType\":6,\"partyId\":1,\"partyOrder\":1}]}}";
/**
* Replace all partyRef with the corresponding partyId.
*
* @throws JSONException
*/
@Test
public void test_03() throws JSONException {
Function<JsonElement, JsonElement> fonction = ancienneValeur -> {
Map<String, Integer> parties = Map.of("REF01", 1, "REF02", 2);
String ancienneValeurAsString = (ancienneValeur.isJsonPrimitive()) ? ancienneValeur.getAsString() : null;
return new JsonPrimitive(parties.get(ancienneValeurAsString));
};
String jsonAfter = jsonParser.apply(JSON_03_INPUT, "partyRef", "partyId", fonction);
JSONAssert.assertEquals(JSON_03_EXPECTED, jsonAfter, false);
}
}