dataweave-selectors

Hello friends,

In this article, we will see some simple and tricky use cases while dealing with selectors in mulesoft integration. This article is only focused on dataweave2 transformations and Mule4.

Dataweave selectors parse input messages and traverse the structure, evaluates it and return the desired output.

Let’s see some of the useful selectors which are covered as part of this article. Also, I have covered some useful scenarios by combining these selectors at the end of this article.

Single-value Selector

For single value selector we can use .keyName syntax. It will return value for matching key.

Input Data

For single value selector check, lets consider a small data-set as given below. Here, I want to fetch the user name from the input.

XML
<users>
  <user>
    <name>Manish</name>    
  </user>
</users>

JSON
{
  "users": {
    "user": {
      "name": "Manish"
    }
  }
}
Single value Dataweave Selector code

Below dataweave expression will work on both input data format.

%dw 2.0
output application/json
---
payload.users.user.name
Output
"Manish"

Multi-value Selector

Single value selector will return single value from the input data. If we have multiple keys with same name it will return first element from the list and will ignore rest of the entries. Here, Multi value selector (.*keyName) is useful and will return Array of values of any matching keys. We need to use * to retrieve multiple values.

Input Data

For Multi value selector check, lets consider a small data-set as given below. Here, I want to fetch the user name from the input. We have more than one keys with same key name “name”.

XML
<users>
  <user>
    <name>Hari</name> 
    <name>Manish</name>   
  </user>
</users>
Json
{
  "users": {
    "user": {
      "name": "Hari",
      "name": "Manish"
    }
  }
}
Multi-Value selector Dataweave code

Below dataweave expression will work on both input data format to retrieve all values against the key “name” at user level.

%dw 2.0
output application/json
---
payload.users.user.*name
Output
[
  "Manish",
  "Hari"
]

Descendants Selector

Descendant selector(..keyName) is very useful while retrieving all the values recursively from node level. It will return Array of values of any matching descendant keys.

Input Data
XML
<users>
  <user>
    <name>Manish</name>
    <user>
      <name>Hari</name>
      <user>
        <name>Niral</name>
      </user>
    </user>
  </user>
</users>
JSON
{
  "users": {
    "user": {
      "name": "Manish",
      "user": {
        "name": "Hari",
        "user": {
          "name": "Niral"
        }
      }
    }
  }
}
Descendants Dataweave code – 1st scenario

Below dataweave expression will work on both input data format to retrieve all values against the key “name” from the input payload.

%dw 2.0
output application/json
---
payload..name
Output
[
  "Manish",
  "Hari",
  "Niral"
]
Descendants Dataweave code – 2nd scenario

With below dataweave expression, if you see the output it is skipping first name entry “Manish” as descendant selector is used 2nd level or depth of the input.

%dw 2.0
output application/json
---
payload.users.user.user..name
Output
[
  "Hari",
  "Niral"
]

Key-value pair Selector

Key-value selector(.&keyName) is used to retrieve the object(key, value) against the matching key.

Input Data
XML
<users>
  <user>
    <name>Hari</name>
    <name>Manish</name>      
  </user>
</users>
JSON
{
  "users": {
    "user": {
      "name": "Hari",
      "name": "Manish"
    }
  }
}
Dataweave key-value pair code
%dw 2.0
output application/json
---
payload.users.user.&name
Output
{
  "name": "Hari",
  "name": "Manish"
}

Combining selectors

Now, lets see some usecase where we need to be extra careful while using these selectors. Lets consider the input below:

XML
<users>
  <user>
    <name>Manish</name>
    <user>
      <name>Preeti</name>
      <user>
        <name>Niral</name>
      </user>
      <name>Ramesh</name>
    </user>
    <name>Hari</name>
  </user>
</users>
JSON
{
  "users": {
    "user": {
      "name": "Manish",
      "user": {
        "name": "Preeti",
        "user": {
          "name": "Niral"
        },
        "name": "Ramesh"
      },
      "name": "Hari"
    }
  }
}

If we only use descendants selector with above input we will not get the proper results. It will select only first element from each node.

%dw 2.0
output application/json
---
payload..name
[
  "Manish",
  "Preeti",
  "Niral"
]

For above scenario, we need to combine multi-value and descendants selector to get all the values properly.

%dw 2.0
output application/json
---
payload..*name
Output
[
  "Manish",
  "Hari",
  "Preeti",
  "Ramesh",
  "Niral"
]

Similarly, if you want to get all the key-value pairs you need to combine key-value selector with descendants selector. It will retrieve all elements from each node and results the output as combined array.

%dw 2.0
output application/json
---
payload..&name
Output
[
  {
    "name": "Manish",
    "name": "Hari"
  },
  {
    "name": "Preeti",
    "name": "Ramesh"
  },
  {
    "name": "Niral"
  }
]

Some of common useful dataweave use-cases that you can check from our previous articles:

Also, there are a lot selectors available in Mulesoft docs which you can explore from here.

Happy Learning 🙂

By Manish Kumar

I am having around 10 years of IT experience in Integration Architecture, Requirement gathering, Effort Estimation, Application Design\Development\Testing and Deployment including 5+ years of experience in MuleSoft ESB and Hybrid Integrations. DevOps and Cloud Integration is my area of interest.

Leave a Reply

Your email address will not be published. Required fields are marked *