Search code examples
arraysjsondataweavemule4

Mule 4 - Look for a value in json and derive corresponding jsons value


Here I need look for a value1 (color/size) in my json arrayObject and map to value2 (yellow/28 inch) of same json array object in mule 4 dataweave. Below is my json input

Kindly note systemAttributeName should not be same as group. Only if group == 'Color', then corresponding systemAttributeName should be populated

JSON Input

{
  "system": "Computer",
  "description": "",
  "details": "",
  "systemDetails": [
    {
      "systemnumber": "A123",
      "description": [
        {
          "group": "color",
          "desc": "yellow"
        },
         {
          "group": "variant",
          "desc": "20k model"
        },
        {
          "group": "category",
          "desc": "Desktop"
        }
      ]
    },
    {
      "systemnumber": "B123",
      "description": [
        {
          "group": "size",
          "desc": "28 inch"
        },
        {
          "group": "category",
          "desc": "Laptop"
        }
      ]
    }
  ]
}

My expected output is as below

{
  "systemId": "A123",
  "systemLevelDetails": [
    {
      "systemAttributeName": "Colordescription", 
      "values": "yellow"
    },// if my corresponding input systemDetails.description has a group 'color' - then this should be present
    {
      "systemAttributeName": "Categorydescription",
      "values": "Desktop"
    }// if my corresponding input systemDetails.description has a group 'category' - then this should be present
  ]
}

{
  "systemId": "B123",
  "systemLevelDetails": [
    {
      "systemAttributeName": "Sizedescription",
      "values": "28inch"
    },// if my corresponding input systemDetails.description has a group 'size' - then this should be present
    {
      "systemAttributeName": "Categorydescription",
      "values": "Laptop"
    }
  ]
}

Let me know how can I achieve this?


Solution

  • Assuming that the output should be an array (because what else could it be?), it just seems to be the same as payload.systemDetails but with the key names changed. One way to do it is to just use map and a nested map for the nested array in description. If only some values in description.group are allowed we can use the filter() function to remove them, by validating if the group value is present in a list of valid values. DataWeave script:

    %dw 2.0
    import capitalize from dw::core::Strings
    output application/json
    var validGroups=["color", "size", "category"]
    ---
    payload.systemDetails map {
        systemId: $.systemnumber,
        systemLevelDetails: $.description 
            filter (validGroups contains $.group)
            map {
                systemAttributeName: capitalize($.group)++"description",
                values: $.desc
            }
    }
    

    Output:

    [
      {
        "systemId": "A123",
        "systemLevelDetails": [
          {
            "systemAttributeName": "Colordescription",
            "values": "yellow"
          },
          {
            "systemAttributeName": "Categorydescription",
            "values": "Desktop"
          }
        ]
      },
      {
        "systemId": "B123",
        "systemLevelDetails": [
          {
            "systemAttributeName": "Sizedescription",
            "values": "28 inch"
          },
          {
            "systemAttributeName": "Categorydescription",
            "values": "Laptop"
          }
        ]
      }
    ]
    

    If you need to process each item of the output array individually just use a <foreach> scope in the flow.