Search code examples
jsonjolt

JOLT transformation to remove json object based on condition


Kindly assist me with the below query. I have a requirement to transform a JSON using JOLT based on a condition. Below is my input JSON.

{
  "body": {
    "Activity": [
      {
        "attributeCode": "ABC",
        "attributeValue": "1200"
      },
      {
        "attributeCode": "DEF",
        "attributeValue": "1400"
      },
      {
        "attributeCode": "GHI",
        "attributeValue": "1600"
      }
    ],
    "NonActivity": {
      "bill": "23Oct11",
      "activityNumber": "6100"
    }
  },
  "header": {
    "id": "010400",
    "referenceNumber": "6100"
  },
  "action": "CREATE"
}

If the action is not CREATE , then I want to fully remove "Activity[]" like below :

{
  "body": {
    "NonActivity": {
      "bill": "23Oct11",
      "activityNumber": "6100"
    }
  },
  "header": {
    "id": "010400",
    "referenceNumber": "6100"
  },
  "action": "CREATE"
}

So far below is what I tried, but the problem is when action is not create , I am getting a null :


[
  {
    "operation": "shift",
    "spec": {
      "action": {
        "CREATE": {
          "@2": ""
        },
        "*": {
          "@(2,body.Activity[&])": ""
        }
      }
    }
  }
]

Solution

  • You can use the following transformation spec :

    [
      {
        "operation": "shift",
        "spec": {
          "body": {
            "@1,action": {
              "CREATE": { // if outer "action" == "CREATE"
                "@2": "&3" // @2 -- > the whole value taken from the 2 levels above(eg. the value of the "body")
                           // &3 -- > the label taken from 3 levels above( eg. "body" )   
              },
              "*": { // if outer "action" != "CREATE"
                "*|@2,NonActivity": "&3.NonActivity"
              }
            }
          },
          "*": "&" // the elements at the top level other than "body"
        }
      }
    ]
    

    Considering the case in that you might have elements other than "Activity" and "NonActivity", better to use the following one :

    [
      {
        "operation": "shift",
        "spec": {
          "body": {
            "Activity": "&1.&.@(2,action)", // assign a label by action's value nested within "Activity" object
            "*": "&1.&"
          },
          "*": "&"
        }
      },
      {
        "operation": "shift",
        "spec": {
          "body": {
            "Activity": { "CREATE": "&2.&1" },
            "*": "&1.&"
          },
          "*": "&"
        }
      }
    ]
    

    In case there is no field like "action": "CREATE" in the input, is there a way to tell JOLT to leave the input as is

    Yes, yet you can tell JOLT to do so by adding an modify-default spec and rearranging like the one below :

    [
      {
        "operation": "modify-default-beta",
        "spec": {
          "action": "ReMoVe"
        }
      },
      {
        "operation": "shift",
        "spec": {
          "body": {
            "Activity": "&1.&.@(2,action)", 
            "*": "&1.&"
          },
          "*": "&"
        }
      },
      {
        "operation": "shift",
        "spec": {
          "body": {
            "Activity": { "CREATE": "&2.&1" },
            "*": "&1.&"
          },
          "*": "&",
          "action": { "ReMoVe": { "": "" }, "*": { "@1": "&2" } }
        }
      }
    ]