Contact Us 1-800-596-4880

DataWeave Value Types

DataWeave functions essentially as a template engine that describes an output structure through the use of elements that may be of various different types.

This document covers the different types of objects you can use to construct your output.

Array

Type ⇒ ':array'

Arrays are represented as a sequences of value expressions.

[ 1, 2 + 2, 3 * 3, $x ]

Array Literal

%dw 1.0
%output application/json
---
[ "My", "three", "words" ]

Conditional Elements

Arrays can define conditional values based on a condition. Wrap the value expression between parentheses and use the when keyword with the condition.

Transform
%dw 1.0
%output application/json
---
[(1) when true, (2) when false]
Output
[1]

Object

Type ⇒ ':object'

Objects are represented as a collection of key: value pairs.

  1. Object: { 'Key' : Value }

  2. Key : 'Qualified Name' 'Attributes'

  3. Qualified Name: 'namespace prefix#name' where the 'namespace prefix#' part is optional

  4. Name: String that represents the name.

  5. Attributes: @('Qualified Name'= value,…​)

Strings must be double quoted to be recognized as strings.

Single Value Objects

If an Object has only one key:value pair, the enclosing curly brackets { } are not required:

Example
%dw 1.0
%output application/xml
---
name: "Annie"

Conditional Elements

Objects can define conditional key: value pairs based on a conditional expression. Wrap the key:value expression between parentheses and use the when keyword with the condition.

%dw 1.0
%output application/xml
---
file: {
  name: "transform",
  (extension: "zip") when payload.fileSystem?
}

This example outputs an additional field called "extension" only when the fileSystem property is present in payload (this field may contain any value, not just "true").

<?xml version="1.0" encoding="UTF-8"?>
<file>
  <name>transform</name>
  <extension>zip</extension>
</file>

If absent:

<?xml version="1.0" encoding="UTF-8"?>
<file>
  <name>transform</name>
</file>

Dynamic Elements

Dynamic elements allow you to add the result of an expression as key:value pairs of an object.

Transform
%dw 1.0
%output application/json
---
{
  a: "a",
  (["b","c","d"] map {'$': $})
}
Output
{
  "a": "a",
  "b": "b",
  "c": "c",
  "d": "d"
}

Dynamic keys

In order to specify a key via an expression, the expression should be wrapped in parentheses.

Transform
%dw 1.0
%output application/json
---
{name: 'Data Weave'} mapObject {(upper $$ as :string) : $}
Output
{
  "NAME": "Data Weave"
}

Conditional Attributes

Attributes can be conditional based on a given condition. Wrap the key:value expression in parentheses and use the when keyword with the condition.

Transform
%dw 1.0
%output application/xml
---
name @((company: "Acme") when false, (transform: "Anything") when true): "DataWeave"
Output
<?xml version='1.0' encoding='US-ASCII'?>
<name transform="Anything">DataWeave</name>

Dynamic Attributes

Dynamic attributes allow you to add the result of an expression as key:value pairs of the attributes set.

Input
{
  "company": "Mule",
  "product": "DataWeave"
}
Transform
%dw 1.0
%output application/xml
---
transformation @((payload)): "Transform from anything to anything"
Output
<?xml version='1.0' encoding='US-ASCII'?>
<transformation company="Mule" product="DataWeave">Transform from anything to anything</transformation>

String

Type ⇒ ':string'

A string can be defined by the use of double quotes or single quotes.

{
  doubleQuoted: "Hello",
  singleQuoted: 'Hello',
}

String interpolation

String interpolation allows you to embed variables or expressions directly in a string.

Transform
%dw 1.0
%output application/json
%var name = "Shoki"
---
{
    Greeting: "Hi, my name is $name",
    Sum: "1 + 1 = $(1 + 1)"
}
Output
{
  "Greeting": "Hi, my name is Shoki",
  "Sum": "1 + 1 = 2"
}

Number

Type ⇒ ':number'

There is only one number type that supports both floating point and integer numbers. There is no loss of precision in any operation, the engine always stores the data in the most performant way that doesn’t compromise precision.

Boolean

Type ⇒ ':boolean'

A boolean is defined by the keywords 'true' and 'false'.

Dates

Dates in DataWeave follow the ISO-8601 standard and are defined between '|' characters.

The date system supports:

  • DateTime

  • Local DateTime

  • Time

  • Local Time

  • Period

  • TimeZone

  • Date

Date

Type ⇒ ':date'

Represented as 'Year'-'Month'-'Date'

The type Date has no time component at all (not even midnight).

Transform
%dw 1.0
%output application/json
---
c: |2003-10-01|
Output
{
  "c": "2003-10-01"
}

Time

Type ⇒ ':time'

Represented as 'Hour':'Minutes':'Seconds'.'Milliseconds'

Transform
%dw 1.0
%output application/json
---
c: |23:59:56|
Output
{
  "c": "23:59:56"
}

TimeZone

Type ⇒ ':timeZone'

Timezones must include a + or a - to be defined as such. |03:00| is a time, |+03:00| is a timezone.

Transform
%dw 1.0
%output application/json
---
c: |-08:00|
Output
{
  "c": "-08:00"
}

DateTime

Type ⇒ ':datetime'

Date time is the conjunction of 'Date' + 'Time' + 'TimeZone'.

Transform
%dw 1.0
%output application/json
---
a: |2003-10-01T23:57:59-03:00|
Output
{
  "a": "2003-10-01T23:57:59-03:00"
}

Local Date Time

Type ⇒ ':localdatetime'

Local date time is the conjunction of 'Date' + 'Time'.

Transform
%dw 1.0
%output application/json
---
a: |2003-10-01T23:57:59|
Output
{
  "a": "2003-10-01T23:57:59"
}

Period

Type ⇒ ':period'

Specifies a period of time. Examples |PT9M| ⇒ 9 minutes , |P1Y| ⇒ 1 Year

Transform
%dw 1.0
%output application/json
---
a: |23:59:56| + |PT9M|
Output
{
  "a": "00:08:56"
}

Date decomposition

In order to access the different parts of the date, special selectors must be used.

Transform
%dw 1.0
%output application/json
---
{
  day: |2003-10-01T23:57:59Z|.day,
  month: |2003-10-01T23:57:59Z|.month,
  year: |2003-10-01T23:57:59Z|.year,
  hour: |2003-10-01T23:57:59Z|.hour,
  minutes: |2003-10-01T23:57:59Z|.minutes,
  seconds: |2003-10-01T23:57:59Z|.seconds,
  offsetSeconds: |2003-10-01T23:57:59-03:00|.offsetSeconds,
  nanoseconds: |23:57:59.700|.nanoseconds,
  milliseconds: |23:57:59.700|.milliseconds,
  dayOfWeek: |2003-10-01T23:57:59Z|.dayOfWeek,
  dayOfYear: |2003-10-01T23:57:59Z|.dayOfYear
}
Output
{
  "day": 1,
  "month": 10,
  "year": 2003,
  "hour": 23,
  "minutes": 57,
  "seconds": 59,
  "offsetSeconds": -10800,
  "nanoseconds": 700000000,
  "milliseconds": 700,
  "dayOfWeek": 3,
  "dayOfYear": 274
}

Changing the Format of a Date

To format dates and times, DataWeave supports some formatting characters that are based on the Java 8 java.time.format package, such as the y, M, and d in the date format yyyy-MM-dd. The following example formats the output of the now DataWeave function to show supported letters:

Transform
%dw 1.0
%output application/json
---
[
  { "dateTime" : now },
  { "era-G" : now as :string { format: "G"} },
  { "year-u" : now as :string {format: "u"} },
  { "year-uu" : now as :string {format: "uu"} },
  { "year-y" : now as :string { format: "y"} },
  { "year-yy" : now as :string { format: "yy"} },
  { "dayOfYear-D" : now as :string { format: "D"} },
  { "monthOfYear-MMMM": now as :string { format: "MMMM"} },
  { "monthOfYear-MMM": now as :string { format: "MMM"} },
  { "monthOfYear-MM": now as :string { format: "MM"} },
  { "monthOfYear-M": now as :string { format: "M"} },
  { "monthOfYear-LL": now as :string { format: "LL"} },
  { "monthOfYear-L": now as :string { format: "L"} },
  { "dayOfMonth-d" : now as :string {format: "d"} },
  { "quarterOfYear-qqq" : now as :string {format: "qqq"} },
  { "quarterOfYear-qq" : now as :string {format: "qq"} },
  { "quarterOfYear-q" : now as :string {format: "q"} },
  { "quarterOfYear-QQQQ" : now as :string {format: "QQQQ"} },
  { "quarterOfYear-QQQ" : now as :string {format: "QQQ"} },
  { "quarterOfYear-QQ" : now as :string {format: "QQ"} },
  { "quarterOfYear-Q" : now as :string {format: "Q"} },
  // Understand "Y" and "YY" thoroughly before using it.
  { "weekBasedYear-YY" : now as :string { format: "YY"} },
  { "weekBasedYear-Y" : now as :string { format: "Y"} },
  { "weekInYear-w" : now as :string {format: "w"} },
  { "weekInMonth-W" : now as :string {format: "W"} },
  { "dayOfWeekAbbreviatedName-E" : now as :string {format: "E"} },
  { "dayOfWeekFullName-EEEE" : now as :string {format: "EEEE"} },
  { "localizedDayOfWeek-eeee" : now as :string {format: "eeee"} },
  { "localizedDayOfWeek-eee" : now as :string {format: "eee"} },
  { "localizedDayOfWeek-ee" : now as :string {format: "ee"} },
  { "localizedDayOfWeek-e" : now as :string {format: "e"} },
  { "localizedDayOfWeek-cccc" : now as :string {format: "cccc"} },
  { "localizedDayOfWeek-ccc" : now as :string {format: "ccc"} },
  { "localizedDayOfWeek-c" : now as :string {format: "c"} },
  { "weekOfMonth-F" : now as :string {format: "F"} },
  { "amORpm-a" : now as :string {format: "a"} },
  // "h" outputs 12 o'clock as 12. Other hours match "K" output.
  { "hourOfDay1to12-h" : now as :string {format: "h"} },
  // "K" outputs 12 o'clock as 0. Other hours match "h" output.
  { "hourOfDay0to11-K" : now as :string {format: "K"} },
  { "clockHourOfAmPm-k" : now as :string {format: "k"} },
  { "hourOfDay0to23-H" : now as :string {format: "H"} },
  { "minuteOfHour-m" : now as :string {format: "m"} },
  { "secondOfMinute-s" : now as :string {format: "s"} },
  { "fractionOfSecond-S" : now as :string {format: "S"} },
  { "millisecondOfDay-A" : now as :string {format: "A"} },
  { "nanosecondCountOfSecond-n" : now as :string {format: "n"} },
  { "nanosecondCountOfDay-N" : now as :string {format: "N"} },
  { "timeZoneID-VV" : now as :string {format: "VV"} },
  { "timeZoneName-zz" : now as :string {format: "zz"} },
  { "localizedZoneOffset-OOOO" : now as :string {format: "OOOO"} },
  { "localizedZoneOffset-O" : now as :string {format: "O"} },
  { "timeZoneOffsetZforZero-XXX" : now as :string {format: "XXX"} },
  { "timeZoneOffsetZforZero-XX" : now as :string {format: "XX"} },
  { "timeZoneOffsetZforZero-X" : now as :string {format: "X"} },
  { "timeZoneOffset-xxx" : now as :string {format: "xxx"} },
  { "timeZoneOffset-xx" : now as :string {format: "xx"} },
  { "timeZoneOffset-x" : now as :string {format: "x"} },
  { "timeZoneOffset-Z" : now as :string {format: "Z"} },
  { "timeZoneOffset-ZZZZ" : now as :string {format: "ZZZZ"} }
 ]

Notice that the use of the syntax {format: "formattingCharacterOrPattern"} to format the date or time.

Output
[
  { "dateTime": "2019-04-10T14:20:14.271-07:00" },
  { "era-G": "AD" },
  { "year-u": "2019" },
  { "year-uu": "19" },
  { "year-y": "2019" },
  { "year-yy": "19" },
  { "dayOfYear-D": "100" },
  { "monthOfYear-MMMM": "April" },
  { "monthOfYear-MMM": "Apr" },
  { "monthOfYear-MM": "04" },
  { "monthOfYear-M": "4" },
  { "monthOfYear-LL": "04" },
  { "monthOfYear-L": "4" },
  { "dayOfMonth-d": "10" },
  { "quarterOfYear-qqq": "2" },
  { "quarterOfYear-qq": "02" },
  { "quarterOfYear-q": "2" },
  { "quarterOfYear-QQQQ": "2nd quarter" },
  { "quarterOfYear-QQQ": "Q2" },
  { "quarterOfYear-QQ": "02" },
  { "quarterOfYear-Q": "2" },
  { "weekBasedYear-YY": "19" },
  { "weekBasedYear-Y": "2019" },
  { "weekInYear-w": "15" },
  { "weekInMonth-W": "2" },
  { "dayOfWeekAbbreviatedName-E": "Wed" },
  { "dayOfWeekFullName-EEEE": "Wednesday" },
  { "localizedDayOfWeek-eeee": "Wednesday" },
  { "localizedDayOfWeek-eee": "Wed" },
  { "localizedDayOfWeek-ee": "04" },
  { "localizedDayOfWeek-e": "4" },
  { "localizedDayOfWeek-cccc": "Wednesday" },
  { "localizedDayOfWeek-ccc": "Wed" },
  { "localizedDayOfWeek-c": "4" },
  { "weekOfMonth-F": "3" },
  { "amORpm-a": "PM" },
  { "hourOfDay1to12-h": "2" },
  { "hourOfDay0to11-K": "2" },
  { "clockHourOfAmPm-k": "14" },
  { "hourOfDay0to23-H": "14" },
  { "minuteOfHour-m": "20" },
  { "secondOfMinute-s": "14" },
  { "fractionOfSecond-S": "2" },
  { "millisecondOfDay-A": "51614271" },
  { "nanosecondCountOfSecond-n": "271000000" },
  { "nanosecondCountOfDay-N": "51614271000000" },
  { "timeZoneID-VV": "America/Los_Angeles" },
  { "timeZoneName-zz": "PDT" },
  { "localizedZoneOffset-OOOO": "GMT-07:00" },
  { "localizedZoneOffset-O": "GMT-7" },
  { "timeZoneOffsetZforZero-XXX": "-07:00" },
  { "timeZoneOffsetZforZero-XX": "-0700" },
  { "timeZoneOffsetZforZero-X": "-07" },
  { "timeZoneOffset-xxx": "-07:00" },
  { "timeZoneOffset-xx": "-0700" },
  { "timeZoneOffset-x": "-07" },
  { "timeZoneOffset-Z": "-0700" },
  { "timeZoneOffset-ZZZZ": "GMT-07:00" }
]

You can combine the formatting letters to write supported date an time formats into a string, using as in the following way:

Transform
%dw 1.0
%output application/json
---
formattedDate: |2003-10-01T23:57:59| as :string {format: "yyyy-MM-dd"}
Output
{
  "formattedDate": "2003-10-01"
}

If you are doing multiple similar conversions in your transform, you might want to define a custom type as a directive in the header and set each date as being of that type.

Transform
%dw 1.0
%output application/json
%type mydate = :string { format: "yyyy/MM/dd" }
---
{
  formattedDate1: |2003-10-01T23:57:59| as :mydate,
  formattedDate2: |2015-07-06T08:53:15| as :mydate
}
Output
{
  "formattedDate1": "2003/10/01",
  "formattedDate2": "2015/07/06"
}

Regular Expression

Type ⇒ ':regex'

Regular Expressions are defined between /. For example /(\d+)/ for represents multiple numerical digits from 0-9. These may be used as arguments in certain operations that act upon strings, like Matches or Replace, or on operations that act upon objects and arrays, such as filters.

Iterators

Type ⇒ ':iterator'

This type is based in the iterator Java class. The iterator contains a collection, and includes methods to iterate through and filter it.

Just like the Java class, the iterator is designed to be consumed only once. For example, if you then pass this value to a logger would result in consuming it and it would no longer be readable to further elements in the flow.

Custom Types

You can define your own custom types in the header of your transform, then in the body you can define an element as being of that type.

To do so, the directive must be structured as following: %type name = java definition

For example:

%dw 1.0
%type currency = :number { format: "##"}
%type user = :object { class: “my.company.User”}

Usually it’s a good idea to extend an existing type rather than creating one from scratch.

For example, above :string defines currency as extending the string type.

To then assign an element as being of the custom type you defined, use the operation as :type after defining a field:

%dw 1.0
%type currency = :number { format: "##"}
%type user = :object { class: “my.company.User”}
---
customer:payload.user as :user

Defining Types For Type Coercion

Format

The metadata 'format' key is used for formatting numbers and dates.

Input
<items>
    <item>
        <price>22.30</price>
    </item>
    <item>
        <price>20.31</price>
    </item>
</items>
Transform
%dw 1.0
%output application/json
%type currency = :number { format: "##"}
---
books: payload.items.*item map
    book:
        price: $.price as :currency
Output
{
  "books": [
    {
      "book": {
        "price": 22.30
      }
    },
    {
      "book": {
        "price": 20.31
      }
    }
  ]
}

In Anypoint Studio, you can define several more values, like separators, quote characters and escape characters. See To Define Input and Output Structure of a Transformation.

Functions and Lambdas

type → :function

In DataWeave, function and lambdas (anonymous functions) are first-class citizen and they can be used inside operators such as a map, mapObject, etc, and can even be assigned to a variable. When using lambdas within the body of a DataWeave file in conjunction with an operator such as map operator, its attributes can either be explicitly named or left anonymous, in which case they can be referenced as $, $$, etc.

Assign to a var

You can define a function as a variable with a constant directive through '%var'

Transport
%dw 1.0
%output application/json
%var toUser = (user) -> {firstName: user.givenName, lastName: user.sn}
---
{
  "user" : toUser({ givenName : "Annie", sn : "Point" })
}
Output
{
  "user": {
    "firstName": "Annie",
    "lastName": "Point"
  }
}

Named attributes with an Operator

This example uses a lambda with an attribute that’s explicitly named as 'name'.

Input
%dw 1.0
%output application/json
---
users: ["john", "peter", "matt"] map ((name) ->  upper name)
Transform
{
  "users": ["JOHN","PETER","MATT"]
}

Anonymous attributes with an Operator

This example uses a lambda with an attribute that’s not explicitly named, and so is referred to by default as '$'.

Transform
%dw 1.0
%output application/json
---
users: ["john", "peter", "matt"] map  upper $
Output
{
  "users": ["JOHN","PETER","MATT"]
}

Declare using function directive

You can declare functions in the Header and these can be invoked at any point in the Body, you can also declare functions anywhere in the body. You refer to them using the form function-name() passing an expression in between the parentheses for each necessary argument. Each expression between the parentheses is evaluated and the result is passed as an argument used in the execution of the function body.

Transform
%dw 1.0
%output application/json
%function toUser(user){firstName: user.givenName, lastName: user.sn}
---
{
  "user" : toUser({ givenName : "Annie", sn : "Point" })
}
Output
{
  "user": {
    "firstName": "Annie",
    "lastName": "Point"
  }
}

Operators Sorted by Type

Below is an index that includes all of the different operators in DataWeave, sorted by the types of the parameters it accepts. Each operator displays what type is accepted on each of its arguments, not all arguments are required.

When you provide an operator with properties that don’t match the expected types, DataWeave automatically attempts to coerce the provided property to the required type.

Operations Performed on any Type

Operator Accepted types for each argument

typeOf

(':any')

as

(':any', ':type')

+

(':any', ':array')

Operations Performed on ':number'

Operator Accepted types for each argument

+

(':number', ':number')

-

(':number', ':number')

*

(':number', ':number')

/

(':number', ':number')

round

(':number')

sqrt

(':number')

pow

(':number', ':number')

ceil

(':number')

floor

(':number')

abs

(':number')

mod

(':number', ':number')

ordinalize

(':number')

Operations Performed on ':array'

Operator Accepted types for each argument

min

(':array')

max

(':array')

sizeOf

(':array')

sum

(':array')

flatten

(':array')

orderBy

(':array', ':function')

reduce

(':array', ':function')

+

(':array', ':any')

-

(':array', ':any')

--

(':array', ':array')

map

(':array', ':function')

avg

(':array')

filter

(':array', ':function')

contains

(':array', ':any')

distinctBy

(':array', ':function')

joinBy

(':array', ':string')

++

(':array', ':array')

groupBy

(':array', ':function')

zip

(':array', ':array')

unzip

(':array')

Operations Performed on ':string'

Operator Accepted types for each argument

trim

(':string')

++

(':string', ':string')

sizeOf

(':string')

capitalize

(':string')

lower

(':string')

upper

(':string')

camelize

(':string')

dasherize

(':string')

underscore

(':string')

singularize

(':string')

pluralize

(':string')

splitBy

(':string', ':string')

splitBy

(':string', ':regex')

find

(':string', ':regex')

find

(':string', ':string')

replace

(':string', ':regex', ':function')

startsWith

(':string', ':string')

endsWith

(':string', ':string')

match

(':string', ':regex')

matches

(':string', ':regex')

scan

(':string', ':regex')

contains

(':string', ':string')

contains

(':string', ':regex')

Operations Performed on ':object'

Operator Accepted types for each argument

sizeOf

(':object')

orderBy

(':object', ':function')

map

(':object', ':function')

mapObject

(':object', ':function')

++

(':object', ':object')

-

(':object', ':name')

--

(':object', ':object')

pluck

(':object', ':function')

Operations Performed on ':datetime'

Operator Accepted types for each argument

>>

(':datetime', ':timezone')

+

(':datetime', ':period')

-

(':datetime', ':period')

-

(':datetime', ':datetime')

Operations Performed on ':date'

Operator Accepted types for each argument

-

(':date', ':date')

++

(':date', ':localtime')

++

(':date', ':time')

++

(':date', ':timezone')

+

(':date', ':period')

-

(':date', ':period')

Operations Performed on ':time'

Operator Accepted types for each argument

-

('#:time', ':time')

++

('#:time', ':date')

+

(':time', ':period')

-

(':time', ':period')

Operations Performed on ':localtime'

Operator Accepted types for each argument

-

(':localtime', ':localtime')

++

(':localtime', ':date')

++

(':localtime', ':timezone')

+

(':localtime', ':period')

-

(':localtime', ':period')

Operations Performed on ':localdatetime'

Operator Accepted types for each argument

-

(':localdatetime', ':localdatetime')

++

(':localdatetime', ':timezone')

+

(':localdatetime', ':period')

-

(':localdatetime', ':period')

Type Coercion Table

In DataWeave, types can be coerced from one type to other using the AS Operator. This table shows the possible combinations and the properties from the schema that are used in the transformation.

When you provide an operator with properties that don’t match the expected types, DataWeave automatically attempts to coerce the provided property to the required type.

Source

Target

Property

:object

:array

(1)

:range

:array

:number

:binary

:string

:binary

:string

:boolean

:number

:datetime

unit

:localdatetime

:datetime

:string

:datetime

format / locale

:datetime

:localdate

:localdatetime

:localdate

:string

:localdate

format / locale

:datetime

:localdatetime

:string

:localdatetime

format / locale

:datetime

:localtime

:localdatetime

:localtime

:time

:localtime

:string

:localtime

format / locale

:datetime

:number

unit

:string

:number

format / locale

:array

:object

:string

:period

:string

:regex

:datetime

:string

format / locale

:localdatetime

:string

format / locale

:localtime

:string

format / locale

:localdate

:string

format / locale

:timetype

:string

format / locale

:period

:string

:timezone

:string

:number

:string

format / locale

:boolean

:string

:range

:string

(2)

:type

:string

:trait

:string

:datetime

:time

:localdatetime

:time

:localtime

:time

:string

:time

format

:datetime

:timezone

:time

:timezone

:string

:timezone

(1) Returns and array with all the values of the object. (2) Returns a string with all the values of the range using "," as the separator

Next Steps