Search code examples
jsonjolt

Transform and manipulate objects within JSON. Dot issue


I have the following JSON and I would like to transform it with Jolt.

JSON Input

{
  "orderNo": "4800001",
  "resourceCode": "test",
  "createdBy": "27150173",
  "action": "R",
  "personId": "R",
  "userId": "test",
  "extraFields": {
    "a": "test",
    "b": "test"
  }
}

Jolt Transform tried

[
  {
    "operation": "shift",
    "spec": {
      "orderNo": {
        "#orderNo": "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow.input[0].key",
        "@": "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow.input[0].value"
      },
      "createdBy": {
        "#identityName": "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow.input[1].key",
        "@": "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow.input[1].value"
      }
    }
  },
  {
    "operation": "default",
    "spec": {
      "schemas": [
        "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow",
        "urn:ietf:params:scim:schemas:sailpoint:1.0:TaskResult"
      ],
      "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow": {
        "workflowName": "Fix"
      }
    }
  }
]

Current Output

{
  "urn:ietf:params:scim:schemas:sailpoint:1": {
    "0:LaunchedWorkflow": {
      "input": [
        {
          "key": "orderNo",
          "value": "test"
        },
        {
          "key": "identityName",
          "value": "test"
        }
      ]
    }
  },
  "schemas": [
    "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow",
    "urn:ietf:params:scim:schemas:sailpoint:1.0:TaskResult"
  ],
  "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow": {
    "workflowName": "Fix"
  }
}

Desired Output

{
  "schemas": [
    "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow",
    "urn:ietf:params:scim:schemas:sailpoint:1.0:TaskResult"
  ],
  "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow": {
    "workflowName": "Fix",
    "input": [
      {
        "key": "orderNo",
        "value": "4800001"
      },
      {
        "key": "identityName",
        "value": "27150173"
      }
    ]
  }
}

The problem is, that I do not know how to handle the dot inside "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow", so it will act as a string (and won't cut it because of the dot). What should be the Jolt spec?


Solution

  • Need to use double backslashes(\\) in order to be able to escape special characters such as dots. So, you can rewrite the specifcation as follows :

    [
      {
        "operation": "shift",
        "spec": {
          "#Fix": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.workflowName",
          "orderNo": {
            "#orderNo": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[0].key",
            "@": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[0].value"
          },
          "createdBy": {
            "#identityName": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[1].key",
            "@": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[1].value"
          }
        }
      },
      {
        "operation": "default",
        "spec": {
          "schemas": [
            "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow",
            "urn:ietf:params:scim:schemas:sailpoint:1.0:TaskResult"
          ]
        }
      },
      {
        "operation": "sort"
      }
    ]
    

    the demo on the site Jolt Transform Demo Using v0.1.1 is :

    enter image description here

    Indeed, using only such a shift transformation suffices :

    [
      {
        "operation": "shift",
        "spec": {
          "#urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow|#urn:ietf:params:scim:schemas:sailpoint:1.0:TaskResult": "schemas",
          "#Fix": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.workflowName",
          "orderNo": {
            "#orderNo": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[0].key",
            "@": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[0].value"
          },
          "createdBy": {
            "#identityName": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[1].key",
            "@": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[1].value"
          }
        }
      }
    ]
    

    Notice that, escaping for the special chars is not needed if the expression is on the right-hand-side and prefixed by #(fixed one)

    Btw, a cleaner code, in which indexes not written one by one such as [0] and [1] , with less hardcoding would be enough for the case if both keys orderNo and createdBy would exactly replicated such as

    [
      {
        "operation": "shift",
        "spec": {
          "#urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow|#urn:ietf:params:scim:schemas:sailpoint:1.0:TaskResult": "schemas",
          "#Fix": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.workflowName",
          "orderNo|createdBy": {
            "$": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[#2].key",
            "@": "urn:ietf:params:scim:schemas:sailpoint:1\\.0:LaunchedWorkflow.input[#2].value"
          }
        }
      }
    ]
    

    so as to get the output as

    {
      "schemas" : [ "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow", "urn:ietf:params:scim:schemas:sailpoint:1.0:TaskResult" ],
      "urn:ietf:params:scim:schemas:sailpoint:1.0:LaunchedWorkflow" : {
        "workflowName" : "Fix",
        "input" : [ {
          "key" : "orderNo",
          "value" : "4800001"
        }, {
          "key" : "createdBy", //not "identityName"
          "value" : "27150173"
        } ]
      }
    }