Free MuleSoft CONNECT Keynote & Expo Pass Available!

Register now+
Nav

DataWeave Selectors

The structures of Objects and Arrays can be navigated using Selector Expressions. Each selector expression returns either an object, an array, or a simple type.

A selector always operates within a given context, which can be a reference to a variable, an object literal, an array literal, or the invocation of a function. As DataWeave processes a selector, a new context is set for further selectors, so you can navigate through the complex structures of arrays and objects by using chains of selectors, who’s depth is limited only by the depth of the current context.

Selector Type Syntax Return Type

Single Value selector

.<key-name>

Value of a key:value pair

Multi Value selector

.*<key-name>

Array with values of key:value pairs

Descendants selector

..<key-name>

Array with values of key:value pairs

Key-Value Pair selector

.&<key-name>

Object with key:value pairs

Indexed selector

[<index>]

Value at selected array index

Range selector

[<index> to <index>]

Array with values from selected indexes

XML Attribute selector

.@<key-name>

Value for selected attribute

All XML Attributes

.@

Object with attributes as key:value pairs

Namespace selector

.#

String of the namespace used at the current key

Note that these selectors return a key:value pair that matches the expression:

  • Single level Explicit selector

  • Descendants selector

  • Indexed selector

? operator: Changes the selector expression that returns a Boolean true or false value to indicate on whether the key exists or not.

Single Value selector

Value selectors may be applied over an Object or an Array.

Over Object

This selector returns the first value whose key matches the expression, that is, payload.name, which returns the value whose key matches name.

Transform

          
       
1
2
3
4
5
6
%dw 2.0
output application/xml
---
{
  address: payload.people.person.address
}
Input

          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "people": {
    "size" : 1,
    "person": {
      "name": "Nial",
      "address": {
        "street": {
          "name": "Italia",
          "number": 2164
        },
        "area": {
          "zone": "San Isidro",
          "name": "Martinez"
        }
      }
    }
  }
}
Output

          
       
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<address>
  <street>
    <name>Italia</name>
    <number>2164</number>
  </street>
  <area>
    <zone>San Isidro</zone>
    <name>Martinez</name>
  </area>
</address>

Over Array

This selector is applied on each of the elements of the array that are of type Object and returns an array with all the selected values

Transform

          
       
1
2
3
4
%dw 2.0
output application/json
---
payload.people.person.address.street
Input

          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{
  "people": [ # (1)
    {
      "person": {
        "name": "Nial",
        "address": {
          "street": {
            "name": "Italia",
            "number": 2164
          },
          "area": {
            "zone": "San Isidro",
            "name": "Martinez"
          }
        }
      }
    },
    {
      "person": {
        "name": "Coty",
        "address": {
          "street": {
            "name": "Monroe",
            "number": 323
          },
          "area": {
            "zone": "BA",
            "name": "Belgrano"
          }
        }
      }
    }
  ]
}
1 As 'people' is an array, this sets the context for searching across both 'person' elements. The result from this selection is always an array.
Output

          
       
1
2
3
4
5
6
7
8
9
10
[ (1)
  {
    "name": "Italia",
    "number": 2164
  },
  {
    "name": "Monroe",
    "number": 323
  }
]
1 The output is always an array. An array is returned even if there’s a single matching value.

Multi Value selector

Multi value selector can either be applied over an Object or an Array.

Over Object

This selector returns an array with all the values whose key matches the expression.

Transform

          
       
1
2
3
4
5
6
%dw 2.0
output application/json
---
{
  users: payload.users.*user
}
Input

          
       
1
2
3
4
5
<users>
  <user>Mariano</user>
  <user>Martin</user>
  <user>Leandro</user>
</users>
Output

          
       
1
2
3
4
5
6
7
{
  "users": [
    "Mariano",
    "Martin",
    "Leandro"
  ]
}

Over Array

The selector is applied on each of the elements of the array that are of type Object and returns an array with all the selected values.

Descendants Selector

This selector is applied to the context using the form ..<field-name> and retrieves the values of all matching key:value pairs in the sub-tree under the current context. Regardless of the hierarchical structure these fields are organized in, they are all placed at the same level in the output.

Transform

         
      
1
2
3
4
5
6
%dw 2.0
output application/json
---
{
  names: payload.people..name (1)
}
Input

         
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "people": {
    "person": {
      "name": "Nial",
      "address": {
        "street": {
          "name": "Italia",
          "number": 2164
        },
        "area": {
          "zone": "San Isidro",
          "name": "Martinez"
        }
      }
    }
  }
}
Output

         
      
1
2
3
4
5
6
7
{
  "names": [
    "Nial",
    "Italia",
    "Martinez"
  ]
}
1 In this example, all of the fields that match the key "name" are placed in a list called "names" regardless of their cardinality in the tree of the input data.

Key-Value Pair Selector

This selector retrieves both the keys and the values of all matching keys pairs in the current context. These are returned as an object, containing these retrieved keys and values.

Transform

         
      
1
2
3
4
5
6
%dw 2.0
output application/xml
---
{
  users: payload.users.&user
}
Input

         
      
1
2
3
4
5
6
7
8
<?xml version='1.0' encoding='US-ASCII'?>
<users>
  <user>Mariano</user>
  <user>Martin</user>
  <user>Leandro</user>
  <admin>Admin</admin>
  <admin>org_owner</admin>
</users>
Output

         
      
1
2
3
4
5
6
<?xml version='1.0' encoding='US-ASCII'?>
<users>
  <user>Mariano</user>
  <user>Martin</user>
  <user>Leandro</user>
</users>

Note that unlike the multi-value selector, the output of this selector is an object, where the original keys for each value are also extracted.

Selecting all the Descendant Key Value Pairs

Transform

          
       
1
2
3
4
5
6
%dw 2.0
output application/json
---
{
  names: payload.people..&name
}
Input

          
       
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "people": {
    "person": {
      "name": "Nial",
      "address": {
        "street": {
          "name": "Italia",
          "number": 2164
        },
        "area": {
          "zone": "San Isidro",
          "name": "Martinez"
        }
      }
    }
  }
}
Output
{
  names: [
    {
      name: "Nial"
    },
    {
      name: "Italia"
    },
    {
      name: "Martinez"
    }
  ]
}

Converting the array of objects into an object of objects

Transform

           
        
1
2
3
4
5
6
7
8
9
%dw 2.0
output application/xml
---
{
  names: (payload.people..&name) reduce (value, aggregator) -> aggregator ++ value
  //Alternative methods
  //names: payload.people..&name reduce ($$ ++ $)
  //names: {(payload.people..&name)}
}
Input

           
        
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "people": {
    "person": {
      "name": "Nial",
      "address": {
        "street": {
          "name": "Italia",
          "number": 2164
        },
        "area": {
          "zone": "San Isidro",
          "name": "Martinez"
        }
      }
    }
  }
}
Output

           
        
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<names>
  <name>Nial</name>
  <name>Italia</name>
  <name>Martinez</name>
</names>

Indexed Selector

The index selector returns the element at the specified position, it can be applied over an Array, an Object or a String

Over Array

This selector can be applied to String literals, Arrays and Objects. In the case of Objects, the value of the key:value pair found at the index is returned. The index is zero based.

  1. If the index is bigger or equal to 0, it starts counting from the beginning.

  2. If the index is negative, it starts counting from the end where -1 is the last element.

Transform

          
       
1
2
3
4
%dw 2.0
output application/json
---
payload.people[1]
Input

          
       
1
2
3
4
5
6
7
8
9
10
11
12
{
  "people": [
        {
          "nameFirst": "Nial",
          "nameLast": "Martinez"
        },
        {
          "nameFirst": "Coty",
          "nameLast": "Belgrano"
        }
    ]
}
Output

          
       
1
2
3
4
{
  "nameFirst": "Coty",
  "nameLast": "Belgrano"
}

When using the Index Selector with a String, the string is broken down into an array, where each character is an index.

Transform

          
       
1
2
3
4
5
output application/json
---
{
  name: "MuleSoft"[0]
}
Output

          
       
1
2
3
{
  "name": "M"
}

Over String

The selector picks the character at a given position, treating the string as an array of characters.

  1. If the index is bigger or equal to 0, it starts counting from the beginning.

  2. If the index is negative, it starts counting from the end.

Transform

          
       
1
2
3
4
5
6
%dw 2.0
output application/json
---
{
  name: "Emiliano"[0]
}
Output

          
       
1
2
3
{
  "name": "E"
}

Over Object

The selector returns the value of the key:value pair at the specified position.

Transform

          
       
1
2
3
4
%dw 2.0
output application/json
---
payload[1]
Input

          
       
1
2
3
4
{
  "nameFirst": "Mark",
  "nameLast": "Nguyen"
}
Output

          
       
1
"Nguyen"

Range selector

Over Array

Range selectors limit the output to only the elements specified by the range on that specific order. This selector allows you to slice an array or even invert it.

Transform

          
       
1
2
3
4
5
6
7
%dw 2.0
output application/json
---
{
  slice: [0,1,2][0..1],
  last: [0,1,2][-1..0]
}
Output

          
       
1
2
3
4
5
6
7
8
9
10
11
{
  "slice": [
    0,
    1
  ],
  "last": [
    2,
    1,
    0
  ]
}

Over String

The Range selector limits the output to only the elements specified by the range on that specific order, treating the string as an array of characters. This selector allows you to slice a string or even invert it.

Transform

          
       
1
2
3
4
5
6
7
%dw 2.0
output application/json
---
{
  slice: "DataWeave"[0..1],
  last: "DataWeave"[-1..0]
}
Output

          
       
1
2
3
4
{
  "slice": "Da",
  "last": "evaeWataD"
}

XML Attribute Selector

In order to query for the attributes on an XML element, the syntax .@<key-name> is used. If you just use .@ (without <key-name>) it returns an object containing all attributes as key:value pairs.

Transform

         
      
1
2
3
4
5
6
7
8
9
10
%dw 2.0
output application/json
---
{
  item: {
    type : payload.product.@type,
    name : payload.product.brand,
    attributes: payload.product.@
  }
}
Input

         
      
1
2
3
<product id="1" type="tv">
  <brand>Samsung</brand>
</product>
Output

         
      
1
2
3
4
5
6
7
8
9
10
{
  "item": {
    "type": "tv",
    "name": "Samsung",
    "attributes": { (1)
      "id": 1,
      "type": "tv"
    }
  }
}
1 The third element in this output retrieves an object with all of the attributes in it, in this case both the id and the type.
Transform

         
      
1
2
3
4
5
6
7
8
9
%dw 2.0
output application/json
---
{
  item: {
    attributes : payload.product.@,
    name : payload.product.brand
  }
}
Output

         
      
1
2
3
4
5
6
7
8
9
{
  "item": {
    "attributes": {
      "id": 1,
      "type": "tv"
    },
    "name": "Samsung"
  }
}

Selecting the key value pair

As selectors only return the value of a key:value pair, in order to get both the key and value, you can use a type conversion to object.

Transform

          
       
1
2
3
4
%dw 2.0
output application/xml
---
user: payload.nameFirst as Object (1)
1 Using the as Object transforms the value into an object that contains the key as well as the value. Without this conversion to object, the returned XML body would simply be <user>Mariano</user>.
Input

          
       
1
2
3
4
{
  "nameFirst": "Mariano",
  "nameLast" : "Doe"
}
Output

          
       
1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<user>
  <nameFirst>Mariano</nameFirst>
</user>

Namespace Selector

The Namespace selector returns the namespace of the current key that it is queried against.

Transform

         
      
1
2
3
4
%dw 2.0
output application/json
---
payload.order.#
Input

         
      
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<ns0:order xmlns:ns0=http://orders.company.com>
  <name>Mark</name>
  <items>42</items>
  <orderdate>2017-01-04</orderdate>
</ns0:order>
Output

         
      
1
"http://orders.company.com"

Selectors modifiers

There are two selectors modifiers: ? and !.

  • The question mark returns true or false whether the keys are present on the structures.

  • The exclamation mark evaluates the selection and fails if any key is not present.

Key Present

Returns true if the specified key is present in the object.

Transform

          
       
1
2
3
4
%dw 2.0
output application/xml
---
present: payload.name?
Input

          
       
1
2
3
{
  "name": "Annie"
}
Output:

          
       
1
2
<?xml version="1.0" encoding="UTF-8"?>
<present>true</present>

In the example above, if a 'name' key does exist in the input, it returns true.

This operation also works with XML attributes:

Transform

          
       
1
2
3
4
5
6
7
8
%dw 2.0
output application/json
---
{
  item: {
    typePresent : payload.product.@type?
  }
}
Input

          
       
1
2
3
<product id="1" type="tv">
  <brand>Samsung</brand>
</product>
Output

          
       
1
2
3
4
5
{
  "item": {
    "typePresent": true
  }
}

You can also use this validation operation as part of a filter:

Transform

          
       
1
2
3
4
%dw 2.0
output application/xml
---
users: payload.users.*name[?($ == "Mariano")]
Input

          
       
1
2
3
4
5
<users>
  <name>Mariano</name>
  <name>Luis</name>
  <name>Mariano</name>
</users>
Output

          
       
1
2
3
4
5
<?xml version="1.0" encoding="UTF-8"?>
<users>
  <name>Mariano</name>
  <name>Mariano</name>
</users>

The example above selects key:value pairs with value "Mariano" ⇒ {name: Mariano, name: Mariano}

Assert Present

Returns an exception if any of the specified keys are not found.

Transform

          
       
1
2
3
4
%dw 2.0
output application/xml
---
present: payload.lastName! (1)
1 Throws the exception "There is no key named 'lastName'".
Input

          
       
1
2
3
{
  "name": "Annie"
}

Exception: "There is no key named 'lastName'"