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

我什至尝试从有效载荷传递路径,然后它被当作字符串。 请推荐

stateNamestateCode这块是一致的吗?如果是这样,您可以这样做:

%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 的答案。