I am trying to convert the following input to the below output using java but not able to get the inner nested attributes at all. So from the below JSON I want to match the product class and subclass and use the correct output from the rules section. So, below, we have Home and Cutlery, I want that section to be matched from the rules and get the attributes of it.
Input
{
"product_class": "Home",
"product_subclass": "Cutlery",
"rules": {
"Home": {
"Cutlery": {
"is_sharp": true,
"is_prohibited_ca": false,
"requires_age_verification": false,
"compliance_policy_id": "CP-1"
},
"Rug": {
"is_sharp": false,
"is_prohibited_ca": true,
"requires_age_verification": true,
"compliance_policy_id": "CP-4"
}
},
"Lighter": {
"Default": {
"is_sharp": false,
"is_hazmat_ground": true,
"is_hazmat_air": true,
"compliance_policy_id": "CP-210"
}
}
}
}
And I have tried the bunch of JOLT specs but not getting success, I just don't get any value in attributes but empty. The latest being the following: Spec used:
[
{
"operation": "default",
"spec": {
"rules": "=@(rules)"
}
},
{
"operation": "shift",
"spec": {
"rules": {
"@(1,product_class)": {
"@(2,product_subclass)": {
"*": "attributes"
}
}
},
"product_class": "product_class",
"product_subclass": "product_subclass"
}
}
]
Expected Output
{
"attributes" : {
"is_sharp" : true,
"is_prohibited_ca" : false,
"requires_age_verification" : false,
"compliance_policy_id" : "CP-1"
},
"product_class" : "Home",
"product_subclass" : "Cutlery"
}
Actual Output:
{
"attributes" : null,
"product_class" : "Home",
"product_subclass" : "Cutlery"
}
Could some one please guide on this and provide an answer. I even tried GPT and it started hallucinating without provide the correct answer! So looking for guidance some help here..
FOLLOW-UP Thank you @Barbaros Ozhen for providing the jolt spec. Now, I am using this in Java where passing the input to the method to scan the rule file accordingly.
Here is my method:
public String transform(String inputJson) throws IOException {
// Parse the input JSON string into a Java Map
Map<String, Object> inputMap = objectMapper.readValue(inputJson, new TypeReference<Map<String, Object>>() {});
// The JOLT transform method can take a "context" map, which allows the spec
// to reference external data. We'll provide our rules here.
Map<String, Object> context = Map.of("rules", this.rules);
// Perform the transformation
Object transformedOutput = chainr.transform(inputMap, context);
// Convert the final Java Object back to a pretty-printed JSON string
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(transformedOutput);
}
...
// Call to above method
String finalOutput = transformer.transform("{\"product_class\": \"Home\", \"product_subclass\": \"Cutlery\"}";);
How should I modify the JOLT spec here when input is separate from the rules file?
The trick is using "@<int>,&"
model as the key element( "@2,&"
in this case ) in order to provide sub-element-wise matching through use of ,&
.
Therefore you can use the following spec :
[
{
"operation": "shift",
"spec": {
"rules": {
"@1,product_class": {
"*": { //the elements of the above node
"@2,&": { //value matching with the aabove node
"@4,product_subclass": { //need to proceed 4 levels upper to arrive the level of this attribute
"*": {
"@2,&": "attributes"
}
}
}
}
}
},
"*": "&" //the elements other than "rules"
}
}
]
the demo on the site Jolt Transform Demo Using v0.1.1 is :