DataWeave Scripts | MuleSoft Documentation
# DataWeave Scripts
DataWeave is the primary data transformation language for use in Mule flows.
You can write standalone DataWeave scripts in Transform Message components, or you can write inline DataWeave expressions to transform data _in-place_ and dynamically set the value of various properties, such as configuration fields in an event processor or global configuration element. Inline DataWeave expressions are enclosed in `#[ ]` code blocks. For example, you can use a DataWeave expression to set conditions in a Choice router or to set the value of a Set Payload or Set Variable component.
The DataWeave code in this example sets a timestamp variable to the current time using the DataWeave `now()` function:
Example: Simple Inline DataWeave Script
```
<set-variable value="#[now()]" variableName="timestamp" doc:name="Set timestamp" />
```

You can also store DataWeave code in external files and read them into other DataWeave scripts, or you can factor DataWeave code into modules (libraries) of reusable DataWeave functions that can be shared by all the components in a Mule app.
## The Structure of DataWeave Scripts
DataWeave scripts and files are divided into two main sections:
  * The Header, which defines directives that apply to the body expression (optional).
  * The Body, which contains the expression to generate the output structure.


When you include a header, the header appears above the body separated by a delimiter consisting of three dashes: `---`.
Here is an example of a DataWeave file with an output directive declared in the header, followed by a DataWeave expression to create a user object that contains two child key/value pairs:
Example: Simple DataWeave Script
```
%dw 2.0
output application/xml
---
{
 user: {
  firstName: payload.user_firstname,
  lastName: payload.user_lastName
 }
}
```

## DataWeave Header
This example shows keywords (such as `import` and `var`) you can use for header directives.
DataWeave Script
```
%dw 2.0
import * from dw::core::Arrays
var myVar=13.15
fun toUser(obj) = {
 firstName: obj.field1,
 lastName: obj.field2
}
type Currency = String { format: "##"}
ns ns0 http://www.abc.com
output application/xml
---
/*
 * Body here.
 * /
```

  * `%dw`: To maintain backward compatibility with a previous version of DataWeave and avoid introducing syntax-breaking changes from the current version, the `%dw` directive supports the specification of a previous DataWeave version on a per script basis. Use of this directive is optional. The default version is 2.0 if the directive is not present. DataWeave versions from 2.0 to 2.4 are identical because no syntax changes occurred in those versions.
Example: `%dw 2.0`
  * `output`: Commonly used directive that specifies the mime type that the script outputs.
Example: `output application/xml`
Valid values: Supported Data Formats.
Default: If no output is specified, the default output is determined by an algorithm that examines the inputs (payload, variables, and so on) used in the script:
    1. If there is no input, the default is `output application/java`.
    2. If all inputs are the same mime type, the script outputs to the same mime type. For example, if all input is `application/json`, then it outputs `output application/json`.
    3. If the mime types of the inputs differ, and no output is specified, the script throws an exception so that you know to specify an output mime type.
Note that only one output type can be specified.
  * `import`: For importing a DataWeave function module. See DataWeave Functions.
  * `var`: Global variables for defining constants that you can reference throughout the body of the DataWeave script:
Example
```
%dw 2.0
var conversionRate=13.15
output application/json
---
{
 price_dollars: payload.price,
 price_localCurrency: payload.price * conversionRate
}
```

For details, see DataWeave Variables.
  * `type`: For specifying a custom type that you can use in the expression.
For a more complete example, see Type Coercion with DataWeave.
  * `ns`: Namespaces, used to import a namespace.
Example
```
%dw 2.0
output application/xml
ns ns0 http://www.abc.com
ns ns1 http://www.123.com
---
{
  ns0#myroot: {
     ns1#secondroot: "hello world"
  }
}
```

  * `fun`: For creating custom functions that can be called from within the body of the script.
Example
```
%dw 2.0
output application/json
fun toUser(user) = {firstName: user.name, lastName: user.lastName}
---
{
 user: toUser(payload)
}
```



### Including Headers in Inline DataWeave Scripts
You can include header directives when you write inline DataWeave scripts by flattening all the lines in the DataWeave script into a single line. For smaller DataWeave scripts, this allows you to quickly apply header directives (without having to add a separate Transform Message component to set a variable), then substitute the variable in the next Event processor.
For example, here is the Mule configuration XML to create the same valid XML output as the previous Transform Message component:
Example: Simple Inline DataWeave Script
```
<set-payload value="#[output application/xml --- { myroot: payload } ]" doc:name="Set Payload" />
```

Note that the DataWeave documentation provides numerous transformation examples.
## DataWeave Body
The DataWeave body contains an expression that generates the output structure. Note that MuleSoft provides a canonical way for you to work on data with the DataWeave model: a query, transform, build process.
Here is simple example that provides JSON input for a DataWeave script:
Example: JSON Input
```
{
  "message": "Hello world!"
}
```

This DataWeave script takes the entire payload of the JSON input above and transforms it to the `application/xml` format.
Example: Script that Outputs application/xml
```
%dw 2.0
output application/xml
---
payload
```

The next example shows the XML output produced from the DataWeave script:
Example: XML Output
```
<?xml version='1.0' encoding='UTF-8'?>
<message>Hello world!</message>
```

The script above successfully transforms the JSON input to XML output.
## Errors (Scripting versus Formatting Errors)
A DataWeave script can throw errors due to DataWeave coding errors and due to formatting errors. So when transforming one data format to another, it is important to keep in mind the constraints of both the language and the formats. For example, XML requires a single root node. If you use the DataWeave script above in the attempt to transform this JSON input to XML, you will receive an error (`Unexpected internal error`) because the JSON input lacks a single root:
Example: JSON Input
```
{
  "size" : 1,
  "person": {
   "name": "Yoda"
  }
}
```

A good approach to the creation of a script is to normalize the input to the JSON-like application/dw format. In fact, if you get an error, you can simply transform your input to `application/dw`. If the transformation is successful, then the error is likely a formatting error. If it is unsuccessful, then the error is a coding error.
This example changes the output format to `application/dw`:
Example: DataWeave Script that Outputs application/dw
```
%dw 2.0
output application/dw
---
payload
```

You can see that the script successfully produces `application/dw` output from the JSON input example above:
Example: application/dw Output
```
{
 size: 1,
 person: {
  name: "Yoda"
 }
}
```

So you know that the previous error (`Unexpected internal error`) is specific to the format, not the coding. You can see that the `application/dw` output above does not provide a single root element, as required by the XML format. So, to fix the script for _XML_ output, you need to provide a single root element to your script, for example:
Example: Script that Outputs application/xml
```
%dw 2.0
output application/xml
---
{
  "myroot" : payload
}
```

Now the output meets the requirements of XML, so when you change the output directive back to `application/xml`, the result produces valid XML output.
Example: XML Output Containing a Single XML Root
```
<?xml version='1.0' encoding='UTF-8'?>
<myroot>
 <size>1</size>
 <person>
  <name>Yoda</name>
 </person>
</myroot>
```

## DataWeave Comments
Comments that use a Java-like syntax are also accepted by DataWeave.
```
%dw 2.0
output application/json
---
/* Multi-line
 * comment syntax */
payload
// Single-line comment syntax
```
You can see that the script successfully produces `application/dw` output from the JSON input example above:
Example: application/dw Output
```
{
 size: 1,
 person: {
  name: "Yoda"
 }
}
```

So you know that the previous error (`Unexpected internal error`) is specific to the format, not the coding. You can see that the `application/dw` output above does not provide a single root element, as required by the XML format. So, to fix the script for _XML_ output, you need to provide a single root element to your script, for example:
Example: Script that Outputs application/xml
```
%dw 2.0
output application/xml
---
{
  "myroot" : payload
}
```

Now the output meets the requirements of XML, so when you change the output directive back to `application/xml`, the result produces valid XML output.
Example: XML Output Containing a Single XML Root
```
<?xml version='1.0' encoding='UTF-8'?>
<myroot>
 <size>1</size>
 <person>
  <name>Yoda</name>
 </person>
</myroot>
```

## DataWeave Comments
Comments that use a Java-like syntax are also accepted by DataWeave.
```
%dw 2.0
output application/json
---
/* Multi-line
 * comment syntax */
payload
// Single-line comment syntax
```

To avoid possible errors in Anypoint Studio, use the multi-line comment syntax(`/*comment here*/`) if the first line in the body of your DataWeave script is a comment. Subsequent script comments can use any syntax (`//comment` or `/*comment*/`)   
---  
## Escape Special Characters
In DataWeave, you use the backslash (`\`) to escape special characters that you are using in an input string.
See Escaping Special Characters for more details.
The _input_ strings in the DataWeave scripts escape special characters, while the _output_ escapes in accordance with the requirements of the output format, which can vary depending on whether it is `application/json`, `application/xml`, `application/csv`, or some other format.
This example escapes the internal double quotation mark that is surrounded by double quotation marks.
DataWeave Example
```
%dw 2.0
output application/json
---
{
  "a": "something",
  "b": "dollar sign (\$)",
  "c": 'single quote (\')',
  "c": "double quote (\")",
  "e": `backtick (\`)`
}
```

Notice that the JSON output also escapes the double quotation marks to make the output valid JSON but does not escape the other characters:
JSON Output
```
{
 "a": "something",
 "b": "dollar sign ($)",
 "c": "single quote (')",
 "c": "double quote (\")",
 "e": "backtick (`)"
}
```

The following example escapes the same characters but outputs to XML.
DataWeave Example
```
%dw 2.0
output application/xml
---
{
 xmlExample:
 {
   "a": "something",
   "b": "dollar sign (\$)",
   "c": 'single quote (\')',
   "d": "double quote (\")",
   "e": `backtick (\`)`
  }
}
```

The XML output (unlike JSON output) is valid without escaping the double quotation marks:
XML Output
```
<?xml version='1.0' encoding='UTF-8'?>
<xmlExample>
 <a>something</a>
 <b>dollar sign ($)</b>
 <c>single quote (')</c>
 <d>double quote (")</d>
 <e>backtick (`)</e>
</xmlExample>
```

## Rules for Declaring Valid Identifiers
To declare a valid identifier, its name must meet the following requirements:
  * It must begin with a letter of the alphabet (a-z), either lowercase or uppercase.
  * After the first letter, the name can contain any combination of letters, numbers, and underscores (`_`).
  * The name cannot match any DataWeave reserved keyword (see Reserved Keywords for a complete list).


Here are some examples of valid identifiers:
  * `a1_3BC_22`


The following table provides examples of invalid identifiers and a description of what makes them invalid:
Identifier | Issue  
---|---  
Cannot start with a number.  
Cannot contain special characters.  
Cannot start with an underscore.  
Cannot be a reserved keyword.  
### Reserved Keywords
Valid identifiers cannot match any of the reserved DataWeave keywords:
  * `and` Reserved as a logical operator
  * `as` Reserved for type coercion
  * `async` Reserved
  * `case` Reserved for `case` statements, for example, to perform pattern matching or for use with the `update` operator
  * `default` Reserved for assigning default values for parameters
  * `do` Reserved for statements
  * `else` Reserved for use in if-else and else-if statements
See Flow Control in DataWeave.
  * `enum` Reserved
  * `false` Reserved as a Boolean value
  * `for` Reserved
  * `fun` Reserved for function definitions in DataWeave Header
  * `if` Reserved for if-else and else-if statements
See Flow Control in DataWeave.
  * `import` Reserved for the `import` directive in DataWeave Header
  * `input` Reserved
  * `is` Reserved
  * `ns` Reserved for namespace definitions in DataWeave Header
  * `null` Reserved as the value `null`
See Null (dw::Core Type).
  * `or` Reserved as a logical operator
  * `output` Reserved for the `output` directive in DataWeave Header
  * `private` Reserved
  * `throw` Reserved
  * `true` Reserved as a Boolean value
  * `type` Reserved for type definitions in DataWeave Header
  * `unless` Reserved
  * `using` Reserved for backward compability and replaced by `do`
See Scope and Flow Control Operators.
  * `var` Reserved for variable definitions in the DataWeave Header
  * `yield` Reserved


## dwl File
In addition to specifying DataWeave scripts in the Transform and other components, you can also specify the scripts in a `.dwl` file. In Studio projects, your script files are stored in `src/main/resources`.
In the Mule app XML, you can use the `${file::filename}` syntax to send a script in a `dwl` file through any XML tag that expects an expression. For example, see the `when expression="${file::someFile.dwl}"` in the Choice router here:
```
<http:listener doc:name="Listener" config-ref="HTTP_Listener_config" path="/test">
 <http:response >
  <http:body ><![CDATA[#[${file::transform.dwl}]]]></http:body>
 </http:response>
</http:listener>
<choice doc:name="Choice" >
 <when expression="${file::someFile.dwl}" >
  <set-payload value="It's greater than 4!" doc:name="Set Payload" />
 </when>
 <otherwise >
  <set-payload value="It's less than 4!" doc:name="Set Payload" />
 </otherwise>
</choice>
```

## See Also
  * DataWeave Selectors
  * DataWeave Functions
  *   * Supported Data Formats
  * Functions and Lambdas