%dw 2.0
output application/json
var x = "words"
---
[ "My", "three", x ]
Value Constructs for Types
DataWeave represents data using values, each of which has a data type associated with it. There are many types, such as strings, arrays, Booleans, numbers, objects, dates, times, and others. Each type supports several ways of creating its values. This topic explores many of the ways you can create them. Before you begin, note that DataWeave version 2 is for Mule 4 apps. For a Mule 3 app, refer to the DataWeave version 1 documentation set in the Mule 3.9 documentation. For other Mule versions, you can use the version selector for the Mule Runtime table of contents.
The types that DataWeave provide are bundled into modules that also contain the related functions.
Types in the dw::Core
module (Core types) are available without having to import the Core module. Other modules need to be imported for their functions and types to be available.
It is important for you to know the values that are possible for each DataWeave type, how to create those values, and the common patterns used:
-
Conditional elements that use
if
expressions for arrays and objects. -
Date Decomposition for accessing different parts of a date
-
Dynamic Keys and Dynamic Elements, which allow you to access parts of an object dynamically
-
Use of Regex (dw::Core Type) expressions
Array (dw::Core Type)
An array can hold elements of any supported type. Here is an example of an array:
CData (dw::Core Type)
XML defines a custom type named CData
, which inherits from and extends String
. It is used to identify a CDATA XML block. It can be used to tell the writer to wrap the content inside CDATA or to check if the input string arrives inside a CDATA block.
%dw 2.0
output application/xml encoding="UTF-8"
---
{
users:
{
user : "Mariano" as CData,
age : 31 as CData
}
}
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user><![CDATA[Mariano]]></user>
<age><![CDATA[31]]></age>
</users>
Date and Time (dw::Core Types)
Dates in DataWeave follow the ISO-8601 standard and literals are defined between |
characters.
The language has the following native date types:
-
Date
-
DateTime
-
LocalDateTime
-
LocalTime
-
Period
-
Time
-
TimeZone
Date
A Date
represented by Year
, Month
, and Day
, specified as |uuuu-MM-dd|
. The Date
type has no time component.
|2003-10-01|
DateTime
A Date and Time within a TimeZone. It is the conjunction of Date
+ Time
+ TimeZone
.
|2003-10-01T23:57:59-03:00|
Period
Period
represents an amount of time. The type takes the following form:
-
P[n]Y[n]M[n]DT[n]H[n]M[n]S
-
P<date>T<time>`
Where the [n] is replaced by the value for each of the date and time elements that follow the [n].
Period
has two subcategories:
-
DatePeriod
A date-based amount of time, for example, 1 year, 2 months, 3 days. Because these expressions are date-based, they cannot be converted to milliseconds. For example, a month does not specify whether it is a month of 31 days or not, nor does a year specify whether it is a leap year. The data expresses just an amount of date. In DataWeave, the syntax is|P1Y|
. -
Duration
A time-based amount of time, for example, 1 second, 2 hours, or 2 days, each of which can be represented in seconds or milliseconds. In DataWeave, the syntax is|PT1H|
.
P
is the duration designator placed at the start of the duration representation.
-
Y
is the year designator (e.g.|P1Y|
) -
M
is the month designator (e.g.|P1M|
) -
D
is the day designator (e.g.|P1D|
)
T
is the time designator that precedes the time components of the representation.
-
H
is the hour designator (e.g.|PT1H|
) -
M
is the minute designator (e.g.|PT1M|
) -
S
is the second designator (e.g.|PT1S|
)
DatePeriod
is useful for date manipulation, such as addition or subtraction.
The following example shows how to subtract one year from a date using DatePeriod
. The return type is a new Date
value:
output application/dw
---
|2003-10-01| - |P1Y|
|2002-10-01|
Duration
is useful as a result of a Date
to Date
subtraction so the amount of time between those two dates can be inferred.
The following example shows how subtracting one Date
value from another returns a Duration
value:
output application/dw
---
|2003-11-01| - |2003-10-01|
|PT744H|
Period Coercion
Because a DatePeriod
value is date-based, it can be coerced to Number
date-based units, such as years
or months
.
The following example shows how to coerce a DatePeriod
value to a Number
value by using different units:
output application/json
---
{
years: |P1Y12M| as Number {unit: "years"},
months: |P8Y12M| as Number {unit: "months"}
}
{
"years": 2,
"months": 108
}
Duration Coercion
Because Duration
is time-based, this type can be coerced to a Number
with different time-based units, such as nanos
, milliseconds
, seconds
, hours
, and days
.
The following example shows how to coerce a Duration
to a Number
by using different units:
output application/json
var period = (|2010-12-10T12:10:12| - |2010-09-09T10:02:10|)
---
{
nanos: period as Number {unit: "nanos"},
millis: period as Number {unit: "milliseconds"},
seconds: period as Number {unit: "seconds"},
hours: period as Number {unit: "hours"},
days: period as Number {unit: "days"}
}
{
"nanos": 7956482000000000,
"millis": 7956482000,
"seconds": 7956482,
"hours": 2210,
"days": 92
}
Deconstruct
A Duration
can be deconstructed into hours
, minutes
and secs
.
The following example shows how to deconstruct a Duration
value:
%dw 2.0
output application/json
var period = (|2010-12-10T12:10:12| - |2010-12-10T10:02:10|)
---
{
hours: period.hours,
minutes: period.minutes,
secs: period.secs,
}
{
"hours": 2,
"minutes": 8,
"secs": 2
}
TimeZone
The Time
relative to Greenwich Mean Time (GMT). A TimeZone
must include a +
or a -
. For example, |03:00|
is a time, while |+03:00|
is a TimeZone
.
|-08:00|
Date Decomposition
To access the different parts of the date, special selectors must be used.
%dw 2.0
output application/json
var myDate = |2003-10-01T23:57:59.700-03:00|
---
{
year: myDate.year,
month: myDate.month,
day: myDate.day,
hour: myDate.hour,
minutes: myDate.minutes,
seconds: myDate.seconds,
milliseconds: myDate.milliseconds,
nanoseconds: myDate.nanoseconds,
quarter: myDate.quarter,
dayOfWeek: myDate.dayOfWeek,
dayOfYear: myDate.dayOfYear,
offsetSeconds: myDate.offsetSeconds
}
{
"year": 2003,
"month": 10,
"day": 1,
"hour": 23,
"minutes": 57,
"seconds": 59,
"milliseconds": 700,
"nanoseconds": 700000000,
"quarter": 4,
"dayOfWeek": 3,
"dayOfYear": 274,
"offsetSeconds": -10800
}
Date and Time Formats
To enable you to format dates and times, DataWeave supports formatting characters, such as the u
(for the year), M
, and d
in the date format uuuu-MM-dd
. These characters are based on the Java 8 java.time.format
package.
For examples, see Format Dates and Times.
Timezone IDs
In addition to accepting time zone values, such as -07:00
, DataWeave also accepts IDs such as America/Buenos_Aires
, America/Los_Angeles
, Asia/Tokyo
, and GMT
.
For examples and a list of supported IDs, see Time Zone IDs and Change a Time Zone.
Enum (dw::Core Type)
This type is based on the Enum Java class.
It must always be used with the class
property, specifying the full Java class name of the class, as shown in this example.
%dw 2.0
output application/java
---
"Male" as Enum {class: "com.acme.GenderEnum"}
Iterator (dw::Core Type)
The Iterator
type is based on the Iterator Java class, that iterates through arrays. Iterator
contains a collection and includes methods to iterate through and filter it.
Note that like the Java class, the iterator is designed to be consumed only once. For example, if a logger consumes the value, the value is no longer readable by subsequent elements in the flow.
Null (dw::Core Type)
DataWeave defines a Null
data type for null
values. It is important to note that null
is the value, while Null
is the type. DataWeave functions do not recognize Null
as
a null
value.
You can determine whether a DataWeave function accepts null
values by
looking in the DataWeave reference documentation for a function signature
that accepts a Null type. For example, the
flatten function has two function
signatures, one of which is flatten(Null): Null
. The signature indicates that
flatten
can accept null
values. The ++
(concatenate) function, which lacks a signature for handling value so the Null
type, does not accept null
.
-
flatten([[1],2,[null],null])
returns[1,2,null,null]
-
"a" ++ null
returns the errorUnable to call `++` with (`String`, `Null`)
.
Number (dw::Core Type)
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 does not compromise precision.
DataWeave provides a mechanism for formatting numeric values and for coercing dates and strings to numbers. The language also provides operators that act on numeric values and includes many functions that take numeric values as arguments.
-
Type Coercion with DataWeave shows how to format a number.
-
mapObject provides an example that coerces a string to a number and formats the number.
-
Period Coercion and Duration Coercion include date coercion examples.
-
Operators describes operators that act on numeric values.
-
avg is one of many DataWeave functions that accepts a numeric value. The
Number
type appears in its function signature,avg(Array<Number>): Number
, which indicates that the function accepts an array of numeric values and returns a numeric value. -
The Numbers module provides helper functions that work on numbers.
Object (dw::Core Type)
Represents any object as a collection of Key:value
pairs, where a Key
is
composed of a Name
and Attributes
.
The Name
type is composed of a String
as the local name and the Namespace
.
Attributes
is composed of an Array of Name:value
pairs. Note that the Key
is not a String
, so it is not possible to compare keys. However, you can get
the local name by performing an as String
type coercion on any value of type
Key
.
%dw 2.0
output application/json
---
{
name: "Annie"
}
Single Value Objects
If an object has only one key:value
pair, the enclosing curly braces { }
are not required:
%dw 2.0
output application/json
---
name: "Annie"
Conditional Elements
Objects can define conditional key-value pairs based on a conditional expression. Conditional elements have the form (key:value) if
condition.
%dw 2.0
output application/xml encoding="UTF-8"
---
file: {
name: "transform",
(extension: "zip") if 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 Keys
To specify a key through an expression, you need to wrap the expression in parentheses.
%dw 2.0
output application/json
var dynamicKey = "language"
---
{
(dynamicKey): "Data Weave"
}
{
"language": "Data Weave"
}
Dynamic Elements
Dynamic elements allow you to add the result of an expression as key:value
pairs of an object. That expression must be either an object
or an array of objects
.
%dw 2.0
output application/json
var x = [
{b: "b"},
{c: "c", d: "d"}
]
var y = {e: "e"}
---
{
a: "a",
(x),
(y)
}
The evaluation parentheses around the variables in the body of the script above ((x)
and (y)
) enable the object constructor curly braces ({ }
) surrounding the body of the script to act on the values of the variables. Specifically, the object constructor curly braces extract the key-value pairs from the values of x
and y
and convert them into a collection of key-value pairs within an object. Without the parentheses (for example, if you use x
instead of (x)
), the script returns an error.
The object constructor curly braces require a data construct that contains one or more key-value pairs, specifically an object, such as { "a":"one", "b":"two"}
, or an array of objects, such as [{"a":"one"},{"b":"two"}]
so that it can produce a valid object. Because the first element within the object constructor curly braces is the key-value pair a: "a"
, the object constructor curly braces leave the pair as the first element in the output object, without any modifications. However, the object constructor curly braces extract the outer-level key-value pairs in the evaluated expressions (x)
and (y)
and append those key-value pairs to the output object.
{
"a": "a",
"b": "b",
"c": "c",
"d": "d",
"e": "e"
}
Conditional XML Attributes
You might want your output to only include certain XML attributes based on a condition. Conditional elements have the form (key:value) if condition
%dw 2.0
output application/xml
---
{
name @(
(company: "Acme") if false,
(transform: "Anything") if true
): "DataWeave"
}
<?xml version='1.0' encoding='US-ASCII'?>
<name transform="Anything">DataWeave</name>
Dynamic XML Attributes
You might want to include a changing set of key:value pairs in a specific location as XML attributes.
{
"company": "Mule",
"product": "DataWeave"
}
%dw 2.0
output application/xml
---
transformation @((payload)): "Transform from anything to anything"
<?xml version='1.0' encoding='US-ASCII'?>
<transformation company="Mule" product="DataWeave">Transform from anything to anything</transformation>
Regex (dw::Core Type)
Regular Expressions are defined between /
. For example /\d+/
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.
String (dw::Core Type)
A string can be defined by the use of double quotes or single quotes.
{
doubleQuoted: "Hello",
singleQuoted: 'Hello',
}
Escaping Special Characters
Use the backslash (\
) to escape special characters in an input string:
-
$
: You need to escape any use of of$
in a string. Otherwise, DataWeave treats the$
as an unnamed parameter for a function and returns the errorUnable to resolve reference of $.
. -
"
: For a string that is surrounded by double quotes, you need to escape any double quote that is part of the string, for example,"a\"bcdef"
. Here, the second double-quote is part of the string that starts with ana
and ends withf
. -
'
For a string that is surrounded by single quotes, you need to escape any single quote that is part of the string: for example,'abcd\'e"f'
. In this example, the second single quote is part of the string that starts with ana
and ends withf
. Notice that you do not need to escape the double quote in this case. -
`
: For a string that is surrounded by backticks (supported in DataWeave version 2), you must escape any backtick that is part of the string: for example,`abc\`def`
. -
\
: Because the backslash is the character you use to escape other special characters, you need to escape it with a separate backslash to use it in a string, for example,\\
. -
\n
: For inserting a new line. -
\t
: For inserting a tab. -
\u
: For inserting a unicode character, such as\u25c4
.
String Interpolation
String interpolation allows you to embed variables or expressions directly in a string. The expression need to be enclosed ($( <expression> )
), and it should always return String type or something that is coercible to String.
%dw 2.0
output application/json
var name = "Shoki"
---
{
Greeting: "Hi, my name is $name",
Sum: "1 + 1 = $(1 + 1)"
}
{
"Greeting": "Hi, my name is Shoki",
"Sum": "1 + 1 = 2"
}
TryResult (dw::Runtime Type)
Evaluates the delegate and returns an object with the result or an error message. See the try
example. A successful TryResult
contains the result
field and a success
value of true
. An unsuccessful TryResult
contains the error
field and a success
value of false
.
{
success: Boolean,
result?: T,
error?: {
kind: String,
message: String,
stack?: Array<String>,
location?: String
}
}
URI Types (dw::core::URL)
Functions in the URI function module can return a URI data type.
{
isValid: Boolean,
host?: String,
authority?: String,
fragment?: String,
path?: String,
port?: Number,
query?: String,
scheme?: String,
user?: String,
isAbsolute?: Boolean,
isOpaque?: Boolean
}
The URI type consists of the following fields:
-
isValid
: Boolean that indicates whether the URI is valid. Invalid characters include<
,>
, and blank spaces. -
host
: String representing the host name (for example,my.company.com
fromhttp://my.company.com:8080/hello
) -
authority
: String representing the authority, which includes the host and port (for example,my.company.com:8080
fromhttp://my.company.com:8080/hello
). Returns the port only if it is explicitly specified in the URI. -
fragment
: String representing the subordinate resource after the#
in the URI (for example,footer
in the URI"https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#footer"
). -
path
: String representing a path following the host or authority (for example,/hello
inhttp://my.company.com:8080/hello
) . -
port
: Number representing an explicit port in the URI (for example,8080
inhttp://my.company.com:8080/hello
). If no port is specified (for example,http://my.company.com/hello
), the value of theport
field isnull
. -
query
: String identifying a query portion of a URI (for example,field=value
in 'http://my.company.com:1234/hello/?field=value'). -
scheme
: String identifying the URI scheme, such ashttps
orhttp
, which appears before a colon (:
). -
user
: String representing user information in a URI (for example, themyname
inhttp://myname@www.mycompany.com
). -
isAbsolute
: Boolean value oftrue
if the URI contains a scheme,false
if the URI does not (for example, a relative URI such as/path/to/somewhere
). -
isOpaque
: Boolean value oftrue
if the URI lacks a scheme followed by forward slashes (/
).mailto:somebody@somewhere.com
returnstrue
.
The following DataWeave script uses the parseURI
function to return and
access values to fields from a URI type. Note that fields with null
values (for example, the URI defined by uriDataTypeEx
) are not returned
unless you explicitly select them.
%dw 2.0
import * from dw::core::URL
var uriDataTypeEx = "https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#footer"
var queryStringsEx = 'http://my.company.com:1234/hello/?field=value'
output application/json
---
{
'myUriDataTypeEx': parseURI(uriDataTypeEx),
// queryStringsEx has a query string:
'myQueryStringsEx': parseURI(queryStringsEx).query,
// uriDataTypeEx lacks a query string:
'myQueryStringNullEx': parseURI(uriDataTypeEx).query,
// The URI includes the port number:
'myAuthorityEx': parseURI('http://localhost:8080/test').authority
}
{
"myUriDataTypeEx": {
"isValid": true,
"raw": "https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#footer",
"host": "en.wikipedia.org",
"authority": "en.wikipedia.org",
"fragment": "footer",
"path": "/wiki/Uniform_Resource_Identifier",
"scheme": "https",
"isAbsolute": true,
"isOpaque": false
},
"myQueryStringsEx": "field=value",
"myQueryStringNullEx": null,
"myAuthorityEx": "localhost:8080"
}