简介:Dataweave是MuleSoft Anypoint平台中的高效数据转换语言,广泛用于处理JSON、XML、CSV等格式。该资源包“dataweave-main”包含多个实用Dataweave脚本示例,帮助开发者快速掌握数据类型、变量、转换操作、字符串处理、数组与对象操作、条件判断、错误处理、外部函数引用等核心功能。通过实际案例学习,用户可显著提升在企业集成和数据处理项目中的实战能力。
1. Dataweave简介与应用场景
Dataweave 是 MuleSoft Anypoint 平台中用于数据转换与处理的核心表达式语言,专为集成场景设计,具备强大的数据解析、格式转换和业务逻辑处理能力。其语法简洁、功能丰富,广泛应用于 API 开发、消息路由、数据清洗和格式转换等关键环节。
随着企业数字化转型加速,系统间的异构数据交互日益频繁,Dataweave 凭借其对 JSON、XML、CSV 等多种数据格式的原生支持,成为连接不同系统、统一数据语义的关键工具。通过本章的学习,读者将掌握 Dataweave 的核心价值及其在现代集成架构中的战略地位。
2. 数据类型与变量定义
在 Dataweave 中,数据类型和变量定义是构建数据转换逻辑的基石。Dataweave 作为 MuleSoft 平台中用于数据处理的核心语言,其对数据类型的处理能力直接影响到数据转换的准确性与灵活性。本章将深入剖析 Dataweave 的基础数据类型、复合数据结构、变量定义机制以及类型转换技巧,帮助读者掌握在实际开发中如何高效地处理数据。
2.1 基础数据类型
Dataweave 支持多种基础数据类型,这些类型构成了所有数据操作的最小单元。理解它们的特性和使用方式,是编写高质量 Dataweave 脚本的前提。
2.1.1 数值类型(Number、Integer、Float)
Dataweave 中的数值类型主要包括 Number 、 Integer 和 Float 。其中:
-
Integer表示整数,例如:123 -
Float表示浮点数,例如:3.14 -
Number是Integer和Float的父类型,可以表示任意数字
代码示例:
%dw 2.0
output application/json
{
intVal: 100,
floatVal: 3.14159,
numberVal: 50 + 30.5
}
逻辑分析:
- intVal 被赋值为整数 100 ,类型为 Integer
- floatVal 被赋值为浮点数 3.14159 ,类型为 Float
- numberVal 是整数与浮点数相加的结果,类型为 Number
参数说明:
- + 运算符会自动进行类型转换,当整数与浮点数相加时,结果将提升为 Float
2.1.2 字符串类型(String)
字符串是 Dataweave 中最常见的数据类型之一,用于表示文本信息。字符串使用双引号或单引号包裹,支持转义字符和字符串插值。
代码示例:
%dw 2.0
output application/json
{
name: "John Doe",
greeting: "Hello, ${name}!",
escaped: "This is a \"quoted\" string"
}
逻辑分析:
- name 是一个标准字符串
- greeting 使用了字符串插值 ${name} ,实现动态拼接
- escaped 展示了如何在字符串中使用转义字符
参数说明:
- ${} 是字符串插值语法,可嵌入任意表达式
- 转义字符 \ 用于表示特殊字符如引号、换行等
2.1.3 布尔类型(Boolean)
布尔类型用于表示逻辑值,取值为 true 或 false 。常用于条件判断和逻辑运算。
代码示例:
%dw 2.0
output application/json
{
isValid: 10 > 5,
isInvalid: 3 == 4,
result: if (isValid) "Pass" else "Fail"
}
逻辑分析:
- isValid 是比较表达式 10 > 5 的结果,返回 true
- isInvalid 是 3 == 4 ,结果为 false
- result 使用 if-else 判断逻辑,返回字符串结果
参数说明:
- 布尔表达式可用于条件判断,控制脚本流程
- 可以与逻辑运算符 and , or , not 结合使用
2.1.4 空值类型(Null)
null 是 Dataweave 中表示空值的特殊类型,常用于表示缺失或未定义的数据。
代码示例:
%dw 2.0
output application/json
{
value: null,
hasValue: value != null
}
逻辑分析:
- value 被显式赋值为 null
- hasValue 判断 value 是否为 null ,结果为 false
参数说明:
- 使用 != null 可判断值是否存在
- null 在逻辑判断中被视为“假”值
2.2 复合数据类型
除了基础类型外,Dataweave 还支持丰富的复合数据结构,用于组织和处理复杂数据。
2.2.1 数组(Array)的基本结构
数组是一种有序的数据集合,可以包含多个元素,元素可以是任意类型。
代码示例:
%dw 2.0
output application/json
{
numbers: [1, 2, 3, 4, 5],
names: ["Alice", "Bob", "Charlie"],
mixed: [1, "two", true, null]
}
逻辑分析:
- numbers 是整数数组
- names 是字符串数组
- mixed 是混合类型数组,展示了数组的灵活性
参数说明:
- 数组使用方括号 [] 定义
- 元素通过索引访问,如 names[0] 返回 "Alice"
2.2.2 对象(Object)的键值对表示
对象是一种无序的键值对集合,类似于 JSON 对象或 Map 结构。
代码示例:
%dw 2.0
output application/json
{
user: {
id: 1,
name: "Alice",
isActive: true
},
address: {
city: "Shanghai",
country: "China"
}
}
逻辑分析:
- user 是一个对象,包含三个字段: id 、 name 和 isActive
- address 是另一个嵌套对象,展示对象嵌套的使用方式
参数说明:
- 对象使用花括号 {} 定义
- 键名可以是字符串或标识符,如 user.name 或 user."name"
2.2.3 函数类型与可调用表达式
Dataweave 支持将函数作为变量传递,实现函数式编程风格。
代码示例:
%dw 2.0
output application/json
{
square: (x) -> x * x,
result: square(5)
}
逻辑分析:
- square 是一个匿名函数,接收参数 x ,返回平方值
- result 调用 square 函数,传入参数 5
参数说明:
- 函数使用箭头语法 (参数) -> 表达式 定义
- 可将函数作为参数传递给其他函数,或作为变量存储
2.3 变量的定义与作用域
在 Dataweave 中,变量用于存储中间结果,提升脚本的可读性和复用性。
2.3.1 使用 var 关键字定义变量
Dataweave 使用 var 关键字声明变量,变量一旦赋值不可更改(不可变性)。
代码示例:
%dw 2.0
output application/json
var name = "Dataweave"
var length = sizeOf(name)
{
message: "Length of ${name} is ${length}"
}
逻辑分析:
- name 被赋值为字符串 "Dataweave"
- length 调用 sizeOf() 函数获取字符串长度
- 最终输出包含变量插值的字符串
参数说明:
- sizeOf() 是 Dataweave 提供的内置函数,用于获取字符串长度
- 所有变量在 var 块中定义,后续通过 --- 分隔符使用
2.3.2 局部变量与全局变量的作用域控制
Dataweave 支持局部变量和全局变量,作用域控制影响变量的可见性。
代码示例:
%dw 2.0
output application/json
var globalVar = "I am global"
{
localScope: do {
var localVar = "I am local"
localVar
},
globalAccess: globalVar
}
逻辑分析:
- globalVar 在顶层定义,作用域为整个脚本
- localVar 在 do 块内定义,作用域仅限于该块
- globalAccess 成功访问全局变量
参数说明:
- 使用 do 块可以定义局部作用域
- 局部变量无法在外部访问,有助于避免命名冲突
2.3.3 变量的生命周期与重用策略
Dataweave 中的变量是不可变的,一旦赋值后无法修改,但可以重复使用。
代码示例:
%dw 2.0
output application/json
var data = [10, 20, 30]
var doubled = data map ((item) -> item * 2)
{
original: data,
processed: doubled
}
逻辑分析:
- data 是原始数组
- doubled 通过 map 函数对数组元素进行乘以 2 的操作
- 原始数据未被修改,而是生成新数组
参数说明:
- Dataweave 遵循不可变性原则,每次操作生成新值
- 变量可以多次用于不同操作,但原始数据保持不变
2.4 数据类型转换技巧
Dataweave 支持灵活的类型转换机制,包括显式和隐式转换,确保数据在不同格式之间自由流动。
2.4.1 显式类型转换函数( as )
使用 as 关键字可以显式地将一个类型转换为另一个类型。
代码示例:
%dw 2.0
output application/json
{
strToNum: "123" as Number,
numToStr: 456 as String,
boolToNum: true as Number
}
逻辑分析:
- "123" 被显式转换为 Number 类型
- 456 被转换为字符串 "456"
- true 转换为 1 , false 转换为 0
参数说明:
- as 操作符用于强制类型转换
- 不支持的转换会抛出异常,如 "abc" as Number
2.4.2 隐式类型转换规则
在某些操作中,Dataweave 会自动进行类型转换,如字符串与数字相加时。
代码示例:
%dw 2.0
output application/json
{
implicit: "The answer is " ++ 42
}
逻辑分析:
- 数字 42 被自动转换为字符串 "42"
- 使用 ++ 运算符实现字符串拼接
参数说明:
- ++ 是字符串拼接运算符,不支持 + 直接拼接字符串和数字
- 隐式转换提高了脚本的灵活性,但也需注意潜在类型错误
2.4.3 类型转换中的常见问题与解决方案
| 问题类型 | 示例 | 解决方案 |
|---|---|---|
| 字符串转数字失败 | "abc" as Number | 使用 try-catch 或正则判断是否为数字 |
| 布尔转字符串问题 | true as String | 显式调用 toString() 函数 |
| 时间格式转换错误 | "2023-01-01" as DateTime | 指定时间格式 as DateTime { format: "yyyy-MM-dd" } |
mermaid 流程图:
graph TD
A[开始类型转换] --> B{数据是否符合目标类型格式?}
B -->|是| C[成功转换]
B -->|否| D[抛出错误]
D --> E[使用 try-catch 捕获异常]
E --> F[提供默认值或提示错误信息]
说明:
- 使用 try-catch 可以避免脚本因类型转换失败而中断执行
- 在转换前使用 is 运算符进行类型检查也是一种有效策略
通过本章内容,读者应已掌握 Dataweave 中的数据类型定义方式、变量作用域控制机制以及类型转换的基本技巧。这些知识为后续的数据处理操作打下坚实基础。
3. 输入与输出格式设置
Dataweave 作为 MuleSoft 平台中用于数据转换和处理的核心语言,其强大之处不仅体现在语法表达的灵活性上,更在于其对多种数据格式的支持与处理能力。在本章中,我们将深入探讨 Dataweave 如何处理输入数据、设置输出格式,并实现格式之间的动态切换。通过本章内容,您将掌握如何灵活配置数据的输入与输出,为后续的复杂数据转换打下坚实基础。
3.1 支持的数据格式概述
Dataweave 支持多种主流数据格式的解析与生成,包括 JSON、XML、CSV 以及表单数据等。这些格式在企业系统集成中扮演着关键角色,尤其是在 API 调用、消息队列、日志处理等场景中。
3.1.1 JSON格式解析与生成
JSON(JavaScript Object Notation)是现代 Web 开发中最常用的数据交换格式之一。Dataweave 提供了原生支持来解析和生成 JSON 数据。
%dw 2.0
output application/json
{
name: "Alice",
age: 30,
isActive: true
}
逐行解读:
-
%dw 2.0:指定使用 Dataweave 2.0 版本。 -
output application/json:声明输出格式为 JSON。 -
---:分隔符,表示脚本主体开始。 -
{}:定义一个 JSON 对象,包含字段name、age和isActive。
参数说明:
- name 是字符串类型;
- age 是整数类型;
- isActive 是布尔类型。
逻辑分析:
该脚本将一个结构化的数据对象转换为 JSON 格式输出,适用于构建 API 响应或中间数据转换场景。
3.1.2 XML格式处理方式
XML(eXtensible Markup Language)在一些传统系统中仍广泛使用。Dataweave 提供了强大的 XML 解析和生成能力,能够轻松处理嵌套结构和命名空间。
%dw 2.0
output application/xml
{
Customer: {
Name: "Bob",
Address: {
Street: "Main St",
City: "New York"
}
}
}
输出结果:
<Customer>
<Name>Bob</Name>
<Address>
<Street>Main St</Street>
<City>New York</City>
</Address>
</Customer>
逻辑分析:
该脚本展示了如何将一个嵌套的对象结构转换为 XML 格式输出。Dataweave 会自动将键名转换为 XML 标签,并处理层级结构。
mermaid流程图:
graph TD
A[Dataweave Script] --> B{判断输出类型}
B -->|JSON| C[生成JSON结构]
B -->|XML| D[生成XML结构]
B -->|CSV| E[生成CSV结构]
3.1.3 CSV与表单数据的转换
CSV(Comma-Separated Values)格式适用于表格类数据的导入导出。Dataweave 能够将数组结构转换为 CSV 格式,也支持反向解析。
%dw 2.0
output application/csv
[
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 }
]
输出结果:
name,age
Alice,30
Bob,25
参数说明:
- name 和 age 是列名;
- 每个对象对应一行数据。
逻辑分析:
该脚本将一个数组结构的数据转换为标准的 CSV 格式,适用于数据导出或批量处理场景。
3.2 输入数据的读取方式
在实际应用中,Dataweave 需要从多种来源读取输入数据,包括消息体、属性、变量等。掌握这些读取方式对于构建灵活的数据处理流程至关重要。
3.2.1 从消息体读取输入
在 MuleSoft 应用中,Dataweave 常用于处理消息体(payload)中的数据。
%dw 2.0
input payload application/json
output application/json
payload map (item, index) -> {
id: item.id,
fullName: item.firstName ++ " " ++ item.lastName
}
逻辑分析:
- input payload application/json :声明输入为 JSON 格式的消息体;
- payload map :对数组中的每个对象进行映射处理;
- 使用 ++ 拼接字符串,生成 fullName 字段。
示例输入:
[
{ "id": 1, "firstName": "John", "lastName": "Doe" },
{ "id": 2, "firstName": "Jane", "lastName": "Smith" }
]
输出结果:
[
{ "id": 1, "fullName": "John Doe" },
{ "id": 2, "fullName": "Jane Smith" }
]
3.2.2 从属性与变量中提取数据
除了消息体,Dataweave 还可以从变量( vars )或属性( attributes )中读取数据。
%dw 2.0
output application/json
{
user: vars.userName,
timestamp: attributes.headers['X-Request-Time']
}
逻辑分析:
- vars.userName :从变量中提取用户名;
- attributes.headers['X-Request-Time'] :从请求头中提取时间戳。
参数说明:
- vars :用于存储流程中定义的变量;
- attributes :用于获取消息的元数据,如 HTTP 请求头、查询参数等。
3.2.3 多数据源合并处理
Dataweave 支持从多个数据源合并数据,例如同时读取消息体和变量。
%dw 2.0
input payload application/json
output application/json
payload map (item) -> {
id: item.id,
name: item.name,
env: vars.environment
}
逻辑分析:
- 每条数据记录中添加了一个 env 字段,其值来自变量 vars.environment ;
- 实现了数据与上下文信息的合并。
3.3 输出格式的配置与优化
输出格式的配置直接影响最终数据的表现形式。本节将介绍如何设置输出格式、控制格式化样式以及设置字符编码。
3.3.1 设置输出格式为JSON/XML/CSV
输出格式通过 output 指令设置,支持 JSON、XML、CSV 等多种类型。
%dw 2.0
output application/xml
{
Root: {
Item: [
{ Name: "Apple", Price: 1.99 },
{ Name: "Banana", Price: 0.59 }
]
}
}
输出结果:
<Root>
<Item>
<Name>Apple</Name>
<Price>1.99</Price>
</Item>
<Item>
<Name>Banana</Name>
<Price>0.59</Price>
</Item>
</Item>
</Root>
3.3.2 输出数据的缩进与格式化控制
可以通过设置 indent 和 pretty 控制输出的缩进和格式。
%dw 2.0
output application/json indent=false
{ name: "Alice", age: 30 }
输出结果:
{"name":"Alice","age":30}
参数说明:
- indent=false :关闭缩进;
- pretty=true :启用美观格式化(默认为 true)。
3.3.3 输出数据的编码与字符集设置
在处理多语言数据时,字符集设置至关重要。可以通过 charset 参数指定输出编码。
%dw 2.0
output application/json charset='UTF-8'
{ message: "你好,世界" }
逻辑分析:
- 输出中文字符,确保使用 UTF-8 编码避免乱码;
- 适用于国际化或日志输出等场景。
3.4 输入输出格式的动态切换
在实际开发中,我们经常需要根据输入数据或业务逻辑动态切换输出格式。
3.4.1 条件判断控制输出格式
通过 if-else 表达式动态控制输出格式。
%dw 2.0
output application/json
if (vars.format == "xml")
output application/xml ---
{ result: "Success" }
else
{ result: "Success" }
逻辑分析:
- 如果 vars.format 为 "xml" ,则输出 XML;
- 否则输出 JSON。
3.4.2 动态格式转换的实践案例
以下是一个实际场景:根据请求头中的 Accept 字段返回不同格式的响应。
%dw 2.0
output application/json
if (attributes.headers.Accept == "application/xml")
output application/xml ---
{ status: "OK" }
else
{ status: "OK" }
参数说明:
- attributes.headers.Accept :HTTP 请求头字段,表示客户端期望的响应格式。
表格对比:
| Accept Header | 输出格式 |
|---|---|
| application/xml | XML |
| application/json | JSON |
| text/csv | CSV |
| 未指定 | 默认 JSON |
逻辑分析:
- 通过判断请求头字段,实现 REST API 的内容协商;
- 提高了接口的通用性和可扩展性。
本章系统地讲解了 Dataweave 在输入与输出格式处理方面的核心能力。通过掌握这些知识,您将能够灵活地处理各种数据格式,构建高效、可维护的数据转换流程。下一章我们将深入探讨 Dataweave 的数据转换操作,包括 map 、 filter 和 reduce 的使用与优化。
4. 数据转换操作(map、filter、reduce)
Dataweave 作为 MuleSoft 平台中的核心数据转换语言,其强大的函数式编程能力使得开发者能够高效地处理复杂的数据结构。在本章中,我们将深入探讨 map 、 filter 和 reduce 这三个最常用且最核心的数据转换操作函数。这些函数不仅构成了数据处理的基石,也是实现数据清洗、格式转换、聚合统计等功能的关键工具。
4.1 数据遍历与映射操作
4.1.1 map函数的语法结构
map 函数是 Dataweave 中用于遍历数组或对象并对每个元素进行处理的函数。其基本语法如下:
%dw 2.0
output application/json
[1, 2, 3] map (item, index) -> item * 2
这段代码将数组 [1, 2, 3] 中的每个元素乘以 2,并返回新的数组 [2, 4, 6] 。
语法说明:
-
map接收两个参数:一个函数和一个可选的索引。 - 函数中的
item表示当前遍历的元素,index是当前元素的索引(从 0 开始)。 -
->是 Lambda 表达式的符号,表示将左侧的输入映射到右侧的输出。
逻辑分析:
- 遍历数组
[1, 2, 3]。 - 对每个元素执行
item * 2。 - 返回新数组
[2, 4, 6]。
4.1.2 在数组和对象中使用map
map 不仅可以用于数组,还可以用于对象的键值对转换。
%dw 2.0
output application/json
{
a: 1,
b: 2,
c: 3
} mapObject (value, key) -> {(key ++ "x"): value * 2}
输出结果:
{
"ax": 2,
"bx": 4,
"cx": 6
}
语法说明:
-
mapObject用于对象的映射操作。 -
value表示当前键对应的值,key是键名。 - 使用
{(key ++ "x"): value * 2}来构造新的键值对。
逻辑分析:
- 遍历对象
{a: 1, b: 2, c: 3}。 - 将每个键追加
x,值乘以 2。 - 返回新对象
{ax: 2, bx: 4, cx: 6}。
4.1.3 map操作的性能优化策略
在处理大规模数据时, map 操作的性能尤为关键。以下是几个优化建议:
| 优化策略 | 说明 |
|---|---|
| 避免嵌套循环 | 尽量减少在 map 内部嵌套其他 map 或 filter 。 |
| 提前计算值 | 将重复计算的值提前计算并缓存。 |
| 使用并行处理 | Dataweave 支持并行处理(如 pmap ),适用于独立任务。 |
| 限制数据量 | 如果不需要全部数据,可在 map 前使用 filter 进行预处理。 |
4.2 数据过滤机制
4.2.1 filter函数的基本用法
filter 用于从数组或对象中筛选符合条件的元素。
%dw 2.0
output application/json
[1, 2, 3, 4, 5] filter ($ > 2)
输出结果:
[3, 4, 5]
语法说明:
-
$是默认变量,表示当前元素。 -
filter ($ > 2)表示保留大于 2 的元素。
逻辑分析:
- 遍历数组
[1, 2, 3, 4, 5]。 - 判断当前元素是否大于 2。
- 保留符合条件的元素
[3, 4, 5]。
4.2.2 多条件过滤与嵌套过滤
filter 支持多条件组合和嵌套使用。
%dw 2.0
output application/json
[1, 2, 3, 4, 5] filter ($ > 2 and $ < 5)
输出结果:
[3, 4]
逻辑分析:
- 遍历数组
[1, 2, 3, 4, 5]。 - 判断当前元素是否同时满足
$ > 2且$ < 5。 - 保留
[3, 4]。
4.2.3 结合map与filter实现复杂逻辑
map 与 filter 的结合可以实现更复杂的转换逻辑。
%dw 2.0
output application/json
[1, 2, 3, 4, 5]
filter ($ % 2 == 0)
map ($ * 2)
输出结果:
[4, 8]
逻辑分析:
- 先通过
filter保留偶数[2, 4]。 - 再通过
map将每个元素乘以 2。 - 返回
[4, 8]。
4.3 数据聚合与计算
4.3.1 reduce函数的工作原理
reduce 用于将数组中的所有元素合并为一个值,常用于求和、计数等场景。
%dw 2.0
output application/json
[1, 2, 3, 4] reduce (acc, val) -> acc + val
输出结果:
10
语法说明:
-
acc是累加器,初始值为数组第一个元素。 -
val是当前元素。 - 每次迭代将
acc + val的结果作为新的acc。
逻辑分析:
- 初始
acc = 1,val = 2→acc = 3 -
val = 3→acc = 6 -
val = 4→acc = 10 - 最终返回
10
4.3.2 使用reduce实现累加、计数等操作
%dw 2.0
output application/json
{
total: [1, 2, 3, 4] reduce (acc, val) -> acc + val,
count: [1, 2, 3, 4] reduce (acc, val) -> acc + 1
}
输出结果:
{
"total": 10,
"count": 4
}
逻辑分析:
-
total是求和。 -
count是计数,每次将累加器加 1。
4.3.3 reduce在对象处理中的应用
reduce 也可用于对象的合并与转换。
%dw 2.0
output application/json
[
{name: "Alice", age: 25},
{name: "Bob", age: 30}
] reduce (acc, item) -> acc ++ { (item.name): item.age }
输出结果:
{
"Alice": 25,
"Bob": 30
}
逻辑分析:
- 初始
acc = {} - 第一个元素
{name: "Alice", age: 25}→acc = {"Alice": 25} - 第二个元素
{name: "Bob", age: 30}→acc = {"Alice": 25, "Bob": 30}
4.4 高级转换技巧
4.4.1 多层嵌套结构的转换策略
处理嵌套结构时,通常需要使用递归或嵌套的 map 和 filter 。
%dw 2.0
output application/json
[
{id: 1, children: [{name: "A"}, {name: "B"}]},
{id: 2, children: [{name: "C"}]}
] map (item) -> {
id: item.id,
names: item.children map $.name
}
输出结果:
[
{
"id": 1,
"names": ["A", "B"]
},
{
"id": 2,
"names": ["C"]
}
]
逻辑分析:
- 对顶层数组使用
map。 - 对每个
children数组使用map提取name字段。
4.4.2 转换过程中的类型判断与处理
使用 case 或 if-else 实现类型判断。
%dw 2.0
output application/json
[1, "a", 3, null, true] map (item) ->
if (item is Number) item * 2
else if (item is String) item ++ "x"
else "unknown"
输出结果:
[2, "ax", 6, "unknown", "unknown"]
逻辑分析:
- 判断每个元素类型:
- 数值乘以 2
- 字符串追加x
- 其他类型返回"unknown"
4.4.3 复杂业务场景下的转换实践
案例:订单数据的字段映射与转换
假设我们有如下原始订单数据:
[
{
"orderId": "1001",
"customer": { "name": "Alice", "email": "alice@example.com" },
"products": [
{ "id": "p1", "price": 10 },
{ "id": "p2", "price": 20 }
]
}
]
目标是将每个订单的总价计算出来,并保留客户信息:
%dw 2.0
output application/json
payload map (order) -> {
orderId: order.orderId,
customer: order.customer,
total: order.products reduce (acc, p) -> acc + p.price
}
输出结果:
[
{
"orderId": "1001",
"customer": {
"name": "Alice",
"email": "alice@example.com"
},
"total": 30
}
]
逻辑分析:
- 遍历每个订单。
- 计算产品总价。
- 构造新的订单对象。
本章系统地介绍了 Dataweave 中的 map 、 filter 和 reduce 函数的使用方法、语法结构、应用场景及性能优化策略。通过这些核心操作,开发者可以高效地处理各种复杂的数据结构,实现从简单转换到复杂业务逻辑的灵活构建。
5. 字符串模板与处理函数
在现代数据集成与API开发中,字符串处理是极为常见且关键的操作。无论是在构建动态消息、处理用户输入、格式化日志,还是进行数据清洗与转换,字符串操作都是不可或缺的一环。Dataweave 提供了丰富的字符串处理功能,包括模板拼接、格式化、截取、替换、正则表达式、日期格式转换以及安全编码等。本章将深入讲解这些功能,并结合实际示例帮助读者掌握其用法。
5.1 字符串拼接与模板语法
在 Dataweave 中,字符串拼接与模板语法是构建动态字符串的基础手段。使用模板字符串可以避免传统字符串拼接的冗长代码,使脚本更清晰、易维护。
5.1.1 使用字符串插值(${})
Dataweave 支持使用 ${} 语法进行字符串插值,允许在字符串中嵌入表达式,从而动态生成内容。
%dw 2.0
output application/json
{
message: "Hello, ${payload.name}! Your age is ${payload.age}."
}
执行逻辑与参数说明:
-
payload.name和payload.age是输入数据中的字段。 -
${}中的表达式会在运行时被计算并插入到字符串中。 - 最终输出的 JSON 对象包含拼接后的消息字符串。
逐行分析:
-
%dw 2.0表示使用 Dataweave 2.0 版本。 -
output application/json定义输出格式为 JSON。 -
message字段使用插值语法将变量name和age动态插入字符串中。
5.1.2 多行字符串与转义字符处理
Dataweave 允许使用三个引号( """ )定义多行字符串,适用于需要换行或保留格式的场景。
%dw 2.0
output application/json
{
multiLine: """This is line one.
This is line two.
This is line three."""
}
参数说明:
- 使用
"""可以定义跨越多行的字符串。 - 换行符
\n会被自动识别,无需手动添加。
转义字符处理:
在字符串中可以使用常见的转义字符,例如:
-
\n表示换行 -
\t表示制表符 -
\"表示双引号
{
escaped: "First line\nSecond line\twith tab"
}
5.1.3 模板字符串的格式化技巧
模板字符串不仅支持变量插值,还支持更复杂的表达式嵌入,如条件判断、函数调用等。
%dw 2.0
output application/json
{
greeting: "Hello, ${if payload.isAdmin then 'Admin' else payload.name}!"
}
逻辑分析:
- 使用
if...then...else判断payload.isAdmin是否为真。 - 若为真,插入
'Admin',否则插入payload.name。 - 这种方式可以构建动态内容,增强脚本的灵活性。
5.2 常用字符串处理函数
Dataweave 提供了丰富的内置字符串处理函数,支持字符串截取、替换、大小写转换、正则匹配等操作,极大提升了开发效率。
5.2.1 字符串截取与替换函数
截取函数: substring
%dw 2.0
output application/json
{
subStr: "Hello World" substring [0 to 5]
}
逻辑分析:
- 使用
substring [start to end]截取从索引0到5的字符串。 - 输出为
"Hello"。
替换函数: replace
{
replaced: "Hello World" replace "World" with "Dataweave"
}
逻辑分析:
- 将
"World"替换为"Dataweave"。 - 结果为
"Hello Dataweave"。
5.2.2 字符串大小写转换
upper 与 lower 函数
{
upperCase: "hello" upper,
lowerCase: "WORLD" lower
}
结果:
{
"upperCase": "HELLO",
"lowerCase": "world"
}
逻辑分析:
-
upper将字符串转为大写。 -
lower将字符串转为小写。
5.2.3 正则表达式在字符串处理中的应用
正则表达式是处理复杂字符串模式的强大工具。Dataweave 支持使用正则表达式进行匹配、替换、提取等操作。
匹配与提取: match
{
matches: "The price is $123.45" match /\$(\d+\.?\d*)/
}
输出结果:
{
"matches": ["$123.45", "123.45"]
}
逻辑分析:
- 使用正则表达式
/\$(\d+\.?\d*)/匹配以$开头的数字。 - 返回匹配结果,第一个元素为完整匹配项,后续为捕获组。
替换: replace 配合正则
{
cleaned: "User: John123" replace /[^a-zA-Z ]+/ with ""
}
输出结果:
{
"cleaned": "User John"
}
逻辑分析:
- 使用正则
/[^a-zA-Z ]+/匹配非字母和空格字符。 - 替换为空字符串,实现字符串清洗。
5.3 字符串与日期时间格式转换
在数据集成中,日期时间格式的转换是常见需求。Dataweave 提供了强大的日期处理函数,支持格式化和解析操作。
5.3.1 日期格式化函数( format )
%dw 2.0
import * from dw::core::Dates
output application/json
{
formattedDate: now() format "yyyy-MM-dd HH:mm:ss"
}
逻辑分析:
- 使用
now()获取当前时间。 - 使用
format函数将时间格式化为"yyyy-MM-dd HH:mm:ss"。 - 输出为当前时间的标准格式字符串。
5.3.2 日期字符串解析( parse )
{
parsedDate: "2023-09-15 14:30:00" parse "yyyy-MM-dd HH:mm:ss"
}
逻辑分析:
- 将字符串
"2023-09-15 14:30:00"按照指定格式解析为日期对象。 - 解析后可用于后续的日期计算或比较。
5.3.3 时间戳与ISO格式的互转
将日期转为时间戳:
{
timestamp: now() as Number
}
将时间戳转为ISO格式:
{
isoDate: 1694795400000 as DateTime
}
逻辑分析:
- 使用
as Number将日期对象转换为毫秒级时间戳。 - 使用
as DateTime将时间戳转换为 ISO 标准格式的日期字符串。
5.4 字符串安全处理与编码转换
在数据传输和 Web 开发中,字符串的安全处理与编码转换至关重要。Dataweave 提供了多种编码与转义函数,确保数据在不同系统中安全传输。
5.4.1 URL编码与解码
%dw 2.0
import * from dw::core::URL
output application/json
{
encoded: encodeURI("https://example.com?query=hello world"),
decoded: decodeURI("https%3A%2F%2Fexample.com%3Fquery%3Dhello%20world")
}
输出结果:
{
"encoded": "https%3A%2F%2Fexample.com%3Fquery%3Dhello%20world",
"decoded": "https://example.com?query=hello world"
}
逻辑分析:
-
encodeURI对 URL 进行编码,确保安全传输。 -
decodeURI将编码后的 URL 解码还原。
5.4.2 HTML实体转义处理
%dw 2.0
import * from dw::core::Strings
{
htmlEscaped: escapeHtml("<p>Hello & Welcome</p>"),
htmlUnescaped: unescapeHtml("<p>Hello & Welcome</p>")
}
输出结果:
{
"htmlEscaped": "<p>Hello & Welcome</p>",
"htmlUnescaped": "<p>Hello & Welcome</p>"
}
逻辑分析:
-
escapeHtml将 HTML 标签与特殊字符转义,防止 XSS 攻击。 -
unescapeHtml可将转义后的 HTML 还原。
5.4.3 Base64编码与解码操作
%dw 2.0
import * from dw::core::Binaries
{
base64Encoded: "Hello Dataweave" encodeWith "base64",
base64Decoded: "SGVsbG8gRGF0YXdlYXZl" decodeWith "base64"
}
输出结果:
{
"base64Encoded": "SGVsbG8gRGF0YXdlYXZl",
"base64Decoded": "Hello Dataweave"
}
逻辑分析:
- 使用
encodeWith "base64"对字符串进行 Base64 编码。 - 使用
decodeWith "base64"将 Base64 字符串还原为原始字符串。
本章小结
| 功能类别 | 核心函数/语法 | 用途说明 |
|---|---|---|
| 字符串拼接 | ${} | 动态插入变量或表达式 |
| 多行字符串 | """ | 支持换行字符串定义 |
| 字符串截取 | substring | 提取指定范围的子字符串 |
| 字符串替换 | replace | 替换指定子串 |
| 正则匹配 | match | 提取符合正则的子串 |
| 日期格式化 | format | 将日期转为指定格式字符串 |
| 日期解析 | parse | 将字符串转为日期对象 |
| URL编码 | encodeURI , decodeURI | 安全传输URL |
| HTML转义 | escapeHtml , unescapeHtml | 防止HTML注入攻击 |
| Base64编码 | encodeWith , decodeWith | 二进制数据的文本传输编码 |
本章内容深入讲解了 Dataweave 中字符串处理的核心功能,涵盖了从基础拼接到高级正则匹配、日期转换与安全编码等关键操作。通过示例代码与详细分析,帮助读者全面掌握字符串处理技巧,为后续复杂数据处理与集成开发打下坚实基础。
6. Dataweave脚本实例解析与实战应用
在前几章中,我们系统地学习了Dataweave的基本语法、数据结构、输入输出格式、数据转换操作以及字符串处理等核心知识。本章将通过多个实战案例,帮助读者将这些知识应用到真实业务场景中,提升脚本编写能力与问题解决能力。
6.1 电商订单数据转换案例
在电商系统中,订单数据常常以CSV格式存储,而在API交互或系统间通信中,往往需要将这些数据转换为JSON格式以方便处理。
6.1.1 需求背景与数据结构分析
假设某电商平台导出的订单数据如下(CSV):
order_id,customer_name,product_name,quantity,price,order_date
1001,John Doe,Smartphone,2,699.99,2023-08-01
1002,Jane Smith,Laptop,1,1299.50,2023-08-02
目标是将其转换为结构清晰、字段命名规范的JSON格式,同时对字段进行映射和类型校验。
6.1.2 将CSV订单数据转换为JSON格式
使用Dataweave读取CSV输入并转换为JSON格式:
%dw 2.0
output application/json
payload map (item, index) -> {
orderId: item.order_id,
customerName: item.customer_name,
productName: item.product_name,
quantity: item.quantity as Number,
totalPrice: item.quantity as Number * item.price as Number,
orderDate: item.order_date as Date
}
参数说明:
-
payload:输入的CSV数据(自动解析为数组对象) -
map:遍历每条订单记录 -
as Number:显式转换字符串为数值类型 -
as Date:将字符串日期转换为Date类型
6.1.3 订单数据的字段映射与校验逻辑
为防止数据异常,可以添加字段校验逻辑,例如检查数量是否为正整数:
%dw 2.0
output application/json
payload map (item, index) -> {
orderId: item.order_id,
customerName: item.customer_name,
productName: item.product_name,
quantity: if (item.quantity as Number > 0) item.quantity else null,
totalPrice: item.quantity as Number * item.price as Number,
orderDate: item.order_date as Date
} filter $.quantity != null
说明:
- 使用
if判断进行字段校验 - 使用
filter过滤掉数量为负或空的记录
6.2 API响应数据清洗与聚合
在微服务架构中,常常需要调用多个API接口获取数据,并进行清洗与聚合处理。
6.2.1 多个API响应的合并处理
假设我们调用了两个API,分别返回用户信息和订单信息:
API1(用户信息):
[
{
"id": 1,
"name": "Alice"
},
{
"id": 2,
"name": "Bob"
}
]
API2(订单信息):
[
{
"userId": 1,
"orderId": "A1001",
"amount": 200
},
{
"userId": 2,
"orderId": "A1002",
"amount": 150
}
]
我们可以使用Dataweave将两个数据源合并:
%dw 2.0
output application/json
(payload[0] zip payload[1]) map ((item, index) -> {
userId: item[0].id,
userName: item[0].name,
orderId: item[1].orderId,
amount: item[1].amount
})
说明:
-
zip:将两个数组按索引配对 -
map:提取字段并组合为统一结构
6.2.2 清洗无效数据与字段标准化
对金额字段进行清洗(去除非数字字符)并统一字段命名:
%dw 2.0
output application/json
payload map (item) -> {
userId: item.userId,
userName: upper(item.userName),
orderId: item.orderId,
amount: (item.amount replace /[^\d.]/ with "") as Number
}
说明:
-
upper:将用户名转换为大写 -
replace:使用正则表达式去除非数字和小数点字符
6.2.3 构建统一的响应格式输出
最终输出格式标准化:
{
"data": payload,
"totalAmount": sum(payload..amount),
"recordCount": sizeOf(payload)
}
6.3 日志数据的解析与分析
在运维和监控场景中,日志数据通常是非结构化的,Dataweave可以通过正则表达式提取关键信息并生成结构化数据。
6.3.1 从日志文本提取结构化数据
日志示例:
[2023-08-01 10:12:34] [INFO] User login: username=alice, ip=192.168.1.1
[2023-08-01 10:13:45] [ERROR] Database connection failed
使用正则表达式提取字段:
%dw 2.0
output application/json
payload splitBy '\n' map (line) -> do {
var pattern = /$\b\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$\s$$([A-Z]+)$$\s(.*)/
var match = line match pattern
---
{
timestamp: match[0][1] as DateTime,
level: match[0][2],
message: match[0][3]
}
}
6.3.2 使用正则表达式匹配关键信息
进一步提取登录日志中的用户名和IP:
match.message match /User login: username=(\w+), ip=(\d+\.\d+\.\d+\.\d+)/
6.3.3 将日志数据转换为指标报表
统计不同日志级别的数量:
{
"infoCount": sizeOf(payload filter $.level == "INFO"),
"errorCount": sizeOf(payload filter $.level == "ERROR")
}
6.4 高级应用场景与最佳实践
6.4.1 复杂条件逻辑的模块化设计
对于复杂的业务逻辑,建议使用函数模块化设计,提高可维护性:
fun formatOrder(order) = do {
var discount = if (order.totalPrice > 1000) 0.1 else 0
---
{
orderId: order.orderId,
finalPrice: order.totalPrice * (1 - discount)
}
}
payload map formatOrder($)
6.4.2 Dataweave脚本的性能优化建议
- 避免在
map或filter中重复计算 - 使用
do块缓存中间结果 - 合理使用
flatten和groupBy减少嵌套层级
6.4.3 与MuleSoft生态的深度集成技巧
在MuleSoft平台中,Dataweave常用于:
- 消息转换(Transform Message组件)
- 数据清洗(结合Set Payload使用)
- 条件路由(结合Choice Router)
例如,在Transform Message组件中使用:
<ee:transform doc:name="Transform Message">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
payload map (item) -> {
id: item.id,
name: upper(item.name)
}]]></ee:set-payload>
</ee:message>
</ee:transform>
(本章未完,下一部分可继续深入探讨Dataweave在复杂业务流程中的高级应用)
简介:Dataweave是MuleSoft Anypoint平台中的高效数据转换语言,广泛用于处理JSON、XML、CSV等格式。该资源包“dataweave-main”包含多个实用Dataweave脚本示例,帮助开发者快速掌握数据类型、变量、转换操作、字符串处理、数组与对象操作、条件判断、错误处理、外部函数引用等核心功能。通过实际案例学习,用户可显著提升在企业集成和数据处理项目中的实战能力。

1391

被折叠的 条评论
为什么被折叠?



