Search code examples
jsonmulemule-componentdataweavemule-esb

Read Array Value Using Dataweave in Mule


I am trying to use dataweave in Mule to read specific data values from an incoming payload. My sample payload looks like below:

 {
    "source": [
        {
            "uri": "entities/1R6xV",
            "createdBy": "API_USER",
            "createdTime": 1562504739146,
            "attributes": {
                "label": "000000000002659654",
                "value": {
                    "Name": [
                        {
                        }
                    ],
                    "Id": [
                        {
                        }
                    ],
                    "Number": [
                        {
                            "type": "config/Types/Number/attributes/Number",
                            "ov": true,
                            "value": "000000000002659654",
                            "uri": "entities/1R6xV/attributes/Num/1ZtyT/Number/60pvN6"
                        }
                    ]
                }
            }
        }
    ]
}

If I need to read the "label", I can achieve that by

label: payload.source.attributes.label

Similarly, how can I read the "value" under attributes > Number. It doesn't work by:

Value: payload.source.attributes.Number.value

I am new to Dataweave. Please advise.


Solution

  • The problem is that the dot selector (.) works on object and on array of objects. When it is applied to an array it will apply the dot selector to all the elements of the array that are of type object and return that result.

    Lets go part by part

    payload.source
    

    Returns

    [
      {
        "uri": "entities/1R6xV",
        "createdBy": "API_USER",
        "createdTime": 1562504739146,
        "attributes": {
          "label": "000000000002659654",
          "value": {
            "Name": [
              {
    
              }
            ],
            "Id": [
              {
    
              }
            ],
            "Number": [
              {
                "type": "config/Types/Number/attributes/Number",
                "ov": true,
                "value": "000000000002659654",
                "uri": "entities/1R6xV/attributes/Num/1ZtyT/Number/60pvN6"
              }
            ]
          }
        }
      }
    ]
    

    So far so good as payload is an Object it returns the value of source that is an array

    payload.source.attributes
    

    Returns

    [
      {
        "label": "000000000002659654",
        "value": {
          "Name": [
            {
    
            }
          ],
          "Id": [
            {
    
            }
          ],
          "Number": [
            {
              "type": "config/Types/Number/attributes/Number",
              "ov": true,
              "value": "000000000002659654",
              "uri": "entities/1R6xV/attributes/Num/1ZtyT/Number/60pvN6"
            }
          ]
        }
      }
    ]
    

    Works ok because the result of payload.source was ended an Array of object so it will do that selection over those objects.

    Now when you execute

    payload.source.attributes.value.Number
    

    It returns

    [
      [
        {
          "type": "config/Types/Number/attributes/Number",
          "ov": true,
          "value": "000000000002659654",
          "uri": "entities/1R6xV/attributes/Num/1ZtyT/Number/60pvN6"
        }
      ]
    ]
    

    That is an array of arrays and here is where it is broken.

    My Solution

    You have two alternatives here

    • Use flatten function

      flatten(payload.source.attributes.value.Number).value

    • Use descendant selector

      payload.source.attributes.value.Number..value