Mule 4:Dataweave2.0:如何将路径作为 属性 传递以获取数据
Mule 4: Dataweave2.0 : how to pass path as property to fetch data
dw2.0 可以从 yaml 属性 文件读取路径吗?
例如说输入是
{
"head": {
"country": "US",
"body": {
"USStates": {
"stateName": "California",
"stateCode": "CL"
}
}
}
}
我必须从上面的请求中获取 stateCode 值。根据国家名称,路径每次都会更改(如 ChinaStates、IndiaStates 等)
那么有没有办法将输入路径作为参数传递给Data weave?我们正在使用 yaml 属性。
我试过下面的代码,结果是空值
%dw 2.0
output application/json
---
if(p("countryName." ++ (payload.head.country as String)) != null)
payload.p("countryName." ++ (payload.head.country))
else "not in scope"
在 yaml 中声明如下
countryName:
US : head.body.USStates.stateCode
INDIA : head.body.IndiaStates.stateCode
我什至尝试从有效载荷传递路径,然后它被当作字符串。
请推荐
stateName
和stateCode
这块是一致的吗?如果是这样,您可以这样做:
%dw 2.0
output application/json
---
{
country: payload.head.country,
stateName: payload.head.body[0].stateName,
stateCode: payload.head.body[0].stateCode
}
输出:
{
"country": "US",
"stateName": "California",
"stateCode": "CL"
}
但是,是的,你可以这样称呼它:
payload.head.body[p('countryName.$(payload.head.country)')].stateCode
应该也可以,但比必要的更复杂。
编辑:
根据您的回答,我明白了为什么这不一定有效。 George 的回答是正确的,但我想我也应该把它扔进去,因为它是一个稍微更完整的函数:
%dw 2.0
output application/json
fun getField(payload: Any, field: String) = do {
var path = field splitBy '.' reduce((pathPart, path=[]) ->
if (pathPart contains '[') do {
var pieces = pathPart splitBy '['
---
pieces reduce((piece,subPath=path) ->
if (piece contains ']') subPath << (piece replace ']' with '') as Number
else subPath << piece
)
}
else path << pathPart
)
---
getField(payload, path)
}
fun getField(payload: Any, field: Array) =
if (sizeOf(log('field',field)) == 1) payload[field[0]]
else getField(payload[field[0]], field[1 to -1])
使用这个函数你会做:
%dw 2.0
output application/json
---
getField(payload, p('country.$(payload.head.country)'))
这是一个通过路径获取字段的函数。
试试这个:
为了简单起见,我确实为路径使用了一个变量,而不是从 YAML 配置中读取它。
%dw 2.0
output application/json
var data = {
"head": {
"country": "US",
"body": {
"USStates": {
"stateName": "California",
"stateCode": "CL"
}
}
}
}
var path = "head.body.USStates.stateCode"
---
path splitBy /\./ reduce (e,acc=data) -> acc[e]
编辑:如果您需要解释,请直接询问,稍后我会重新编辑所有详细信息。现在没时间:).
Edit1:查看此 以获得对 reduce
的解释。
对于内置选择器来说,结构似乎太复杂了。我认为您不能以这种方式在动态表达式中使用 DataWeave 单值选择器(点“.”)。如果您只在 属性 中保留属性名称,它将起作用。我建议尽可能简化数据。
示例:
属性 countrName.US: "美国"
和表达式:
payload.head.body[p("countrName.US")].stateCode
否则,如果您确实需要路径表达式,请参阅 George 的答案。
dw2.0 可以从 yaml 属性 文件读取路径吗?
例如说输入是
{
"head": {
"country": "US",
"body": {
"USStates": {
"stateName": "California",
"stateCode": "CL"
}
}
}
}
我必须从上面的请求中获取 stateCode 值。根据国家名称,路径每次都会更改(如 ChinaStates、IndiaStates 等)
那么有没有办法将输入路径作为参数传递给Data weave?我们正在使用 yaml 属性。 我试过下面的代码,结果是空值
%dw 2.0
output application/json
---
if(p("countryName." ++ (payload.head.country as String)) != null)
payload.p("countryName." ++ (payload.head.country))
else "not in scope"
在 yaml 中声明如下
countryName:
US : head.body.USStates.stateCode
INDIA : head.body.IndiaStates.stateCode
我什至尝试从有效载荷传递路径,然后它被当作字符串。 请推荐
stateName
和stateCode
这块是一致的吗?如果是这样,您可以这样做:
%dw 2.0
output application/json
---
{
country: payload.head.country,
stateName: payload.head.body[0].stateName,
stateCode: payload.head.body[0].stateCode
}
输出:
{
"country": "US",
"stateName": "California",
"stateCode": "CL"
}
但是,是的,你可以这样称呼它:
payload.head.body[p('countryName.$(payload.head.country)')].stateCode
应该也可以,但比必要的更复杂。
编辑:
根据您的回答,我明白了为什么这不一定有效。 George 的回答是正确的,但我想我也应该把它扔进去,因为它是一个稍微更完整的函数:
%dw 2.0
output application/json
fun getField(payload: Any, field: String) = do {
var path = field splitBy '.' reduce((pathPart, path=[]) ->
if (pathPart contains '[') do {
var pieces = pathPart splitBy '['
---
pieces reduce((piece,subPath=path) ->
if (piece contains ']') subPath << (piece replace ']' with '') as Number
else subPath << piece
)
}
else path << pathPart
)
---
getField(payload, path)
}
fun getField(payload: Any, field: Array) =
if (sizeOf(log('field',field)) == 1) payload[field[0]]
else getField(payload[field[0]], field[1 to -1])
使用这个函数你会做:
%dw 2.0
output application/json
---
getField(payload, p('country.$(payload.head.country)'))
这是一个通过路径获取字段的函数。
试试这个:
为了简单起见,我确实为路径使用了一个变量,而不是从 YAML 配置中读取它。
%dw 2.0
output application/json
var data = {
"head": {
"country": "US",
"body": {
"USStates": {
"stateName": "California",
"stateCode": "CL"
}
}
}
}
var path = "head.body.USStates.stateCode"
---
path splitBy /\./ reduce (e,acc=data) -> acc[e]
编辑:如果您需要解释,请直接询问,稍后我会重新编辑所有详细信息。现在没时间:).
Edit1:查看此 reduce
的解释。
对于内置选择器来说,结构似乎太复杂了。我认为您不能以这种方式在动态表达式中使用 DataWeave 单值选择器(点“.”)。如果您只在 属性 中保留属性名称,它将起作用。我建议尽可能简化数据。
示例:
属性 countrName.US: "美国"
和表达式:
payload.head.body[p("countrName.US")].stateCode
否则,如果您确实需要路径表达式,请参阅 George 的答案。