MULE DataWeave Language Map操作符使用

工具版本
mule-standalone3.9.0
Anypoint-Studio6.4.0

遍历操作是编程中经常使用到的操作,在DataWeave Language中,遍历需要使用到的是操作符是Map。同时也借Map操作符来进一步了解DataWeave Language的使用规律,毕竟操作符语法之间并不存在太大差异,彻底掌握一个操作符的运用后,那么其他操作符使用起来相信也不会太难了。

Returns an array that is the result of applying a transformation function (lambda) to each of the elements. The lambda is invoked with two parameters: index and the value. If these parameters are not named, the index is defined by default as $$ and the value as $.

首先这段话有一个奇怪的名词,那就是lambda(即数学里面的λ),经过网上搜索,Mule使用了lambda表达式。如果想了解lambda表达式,或许可以看一下这篇我找的博文,从java角度解释lambda 点这里
官网说,这个Map操作符返回一个array,这个array是经过function(λ)处理后的结果。λ有两个参数,一个是value,一个是index。如果这两个参数没有被命名,value使用$代替,index使用$$代替。
官网给出了一个直观的例子:

%dw 1.0
%output application/json
---
users: ["john", "peter", "matt"] map ((firstName, position) -> position ++ ":" ++ upper firstName)

其中map ((firstName, position) -> position ++ ":" ++ upper firstName)就是一个lambda表达式,请注意第一个参数是value,第二个参数是index。正如上面所说,参数没有命名才使用$符号来代替。而表达式中->是lambda的语法。不必太纠结于lambda的语法,重点关注点是->后的内容,因为这里才是输出的结构定义。处理的输入是[“john”, “peter”, “matt”],然后通过map操作符会使得每一个数组元素都按照你所设置的格式转变。
而需要注意,++符号不是自增的意思,而是DataWeave里面的字符串拼接符号。如果你使用一个+则会报错。upper也是关键字,作用使value值大写。
最后的输出结果如下:

{
    "users": [
        "0:JOHN", 
        "1:PETER", 
        "2:MATT"
    ]
}

上面官网给出的例子结构上简单,因此下面准备了一个XML输入,相对结构复杂点。将其按照要求转为所需JSON格式。
XML输入

<?xml version='1.0' encoding='UTF-8'?>
<orders>
    <order>
        <product>
            <price>5</price>
            <model>MuleSoft Connect 2016</model>
        </product>
        <item_amount>3</item_amount>
        <payment>
            <payment-type>credit-card</payment-type>
            <currency>USD</currency>
            <installments>1</installments>
        </payment>
        <buyer>
            <email>mike@hotmail.com</email>
            <name>Michael</name>
            <address>Koala Boulevard 314</address>
            <city>San Diego</city>
            <state>CA</state>
            <postCode>1345</postCode>
            <nationality>USA</nationality>
        </buyer>
        <shop>main branch</shop>
        <salesperson>Mathew Chow</salesperson>
    </order>
    <order>
        <product>
            <price>10086</price>
            <model>MuleSoft Connect 2018</model>
        </product>
        <item_amount>2333</item_amount>
        <payment>
            <payment-type>credit-card</payment-type>
            <currency>USD</currency>
            <installments>1</installments>
        </payment>
        <buyer>
            <email>cgydawn@hotmail.com</email>
            <name>cgydawn</name>
            <address>beijing,china 314</address>
            <city>San Diego</city>
            <state>AC</state>
            <postCode>123456</postCode>
            <nationality>USA</nationality>
        </buyer>
        <shop>meiyijia shop</shop>
        <salesperson>zhangsan</salesperson>
    </order>
</orders>

XML里面根元素是orders,里面包含两个订单信息。每个订单信息里面又包含产品信息,产品购买数量,支付信息,买家信息,购买地点,销售员名信息。这些信息里面部分还有子信息。

获取该XML输入中买家的信息

达到目标的DataWeave语句

%dw 1.0
%output application/json
---
userInfo : payload.orders map {
    email : $.buyer.email,
    name : $.buyer.name,
    address : $.buyer.address,
    city : $.buyer.city,
    state : $.buyer.state,
    postCode : $.buyer.postCode,
    nationality : $.buyer.nationality
}

JSON输出

需要注意:一开始的时候,按照遍历的想法,我几乎想也不想地直接写出这样的语句

%dw 1.0
%output application/json
---
userInfo : payload map {
    email : $.order.buyer.email
}

获取不完全正确

这样的语句并没有报错,同时还有输出,但是仅仅只输出了第一个订单的电子邮箱信息,然而目标输入是有两个订单信息的。那为什么没有遍历两次而只有一次?对比就知道实际是payloadpayload.orders的差别。如果你使用前者,按照我的理解,map拿去遍历的长度相当于orders数量,即1。但是使用后者,map拿去遍历的长度相当于order长度,即2。同时也应该留意到,map前的格式,会影响到你后续使用的层级关系。
使用payload给map操作符处理,则map直接处理的是payload(),$从其直接子元素order开始执行。
使用payload.orders给map操作符处理,则map直接处理的是payload.orders(),$从其直接子元素product,item_amount,payment,buyer之一开始。
因为需要获取的是买家信息,因此大括号内用的是$.buyer.xxx形式,当然使用$.product.model也是可以的,但那就不是获取买家信息了。


Using Map on an Object(对一个Object进行Map操作)

Map操作符除了对数组类的数据进行处理外,官网还提示它可以对对象进行处理。官网例子将XML输入转为JSON输出,并且将不同价位的美元价格按照给出的固定汇率转为新的价格。
XML输入

<?xml version='1.0' encoding='UTF-8'?>
<prices>
    <basic>9.99</basic>
    <premium>53</premium>
    <vip>398.99</vip>
</prices>

正确DataWeave语句一

%dw 1.0
%output application/json
%var conversionRate=13.45
---
priceList: payload.prices map (
  '$$':{
    dollars: $,
    localCurrency: $ * conversionRate
  }
)

正确DataWeave语句二

%dw 1.0
%output application/json
%var conversionRate=13.45
---
priceList: payload.prices map ((money, position) ->
  '$position':{
    dollars: money,
    localCurrency: money * conversionRate
  }
)

需要注意的是,语句二的语法形式上要求,如果index已经有了命名,则使用index时,需要在命名前加上$,然后用单引号包括。即'$position' 等价于 $$ 。 同时,index参数是可选的,因此下面形式也是正确的,只是不能输出索引信息。
正确DataWeave语句三

%dw 1.0
%output application/json
%var conversionRate=13.45
---
priceList: payload.prices map ((money) ->
  {
    dollars: money,
    localCurrency: money * conversionRate
  }
)

参考资料
官网Map操作符说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值