问题描述
我正在将一个 excel 文件 (.xlsx) 读取到一个 json 数组中,并且我正在创建一个映射,因为我想分别对每一列应用验证。我可以像这样使用列名访问它, Excel文件是:
column A,column B
value of Column A,value of column B
我是这样访问的: 有效载荷映射(项目,索引)-> "列名 A" : item."列名 A",“列名 B”:项目。“列名 B”
其中 A 列和 B 列是 excel 列标题。
我想要做的是创建相同的地图,但使用列索引
payload map(item,index) ->
item[0].key : item[0],item[1].key : item[1]
这样我就不必对 excel 标题名称进行硬编码,而且我可以依赖 excel 列的索引。
我尝试使用 pluck $$ 创建键映射,但我无法创建键值映射,我无法使用 item[0] 作为映射中的键。
预期的输出应该是这样的:
{
"Column A " : "value of Column A","Column B" : "value of Column B","Errors" : "Column A is not valid"
}
解决方法
尝试仅使用索引。它应该可以正常工作。
%dw 2.0
output application/json
---
({ "someKey": "Val1","lksajdfkl": "Val2" })[1]
结果
"Val2"
如果你想使用一个变量作为键,你必须把它用括号括起来。
EG,要将 { "key": "SomeOtherKey","val": 123 }
转换为 { "SomeOtherKey": 123 }
,您可以执行 (payload.key): payload.val
假设您想验证从 Excel 文件加载的每个有效负载项,您可以使用以下 DataWeave 表达式:
%dw 2.0
output application/json
fun validate(col,val) =
if (isEmpty(val)) {"error": col ++ ": value is null or empty"}
else {}
fun validateRow(row) =
"Errors":
flatten([] << ((row mapObject ((value,key,index) -> ((validate((key),value))))).error default []))
---
payload map (item,index) -> item ++ validateRow(item)
使用以下输入负载:
[
{"col1": "val1.1","col2": "val1.2","col3": "val1.3"},{"col1": "val2.1","col2": "val2.2","col3": null}
]
会导致:
[
{
"col1": "val1.1","col3": "val1.3","Errors": [
]
},{
"col1": "val2.1","col3": null,"Errors": [
"col3: value is null or empty"
]
}
]
该表达式将导致输出与您期望的略有不同,但此版本将允许您拥有一系列错误消息,以便稍后在您的流程中更容易操作。
要记住的一件事是每列可能有多个错误消息。如果是这种情况,则 DataWeave 表达式需要进行一些调整。
,试试这个:
%dw 2.0
output application/json
var rules = {
"0": {
key: "Column A",val: (val) -> !isEmpty(val),},"1": {
key: "Column B",val: (val) -> val ~= "value of Column B"
}
}
fun validate(v,k,i) =
[
("Invalid column name: '$(k)' should be '$(rules[i].key)'") if (rules[i]? and rules[i].key? and k != rules[i].key),("Invalid value for $(rules[i].key): '$(v default "null")'") if (rules[i]? and rules[i].val? and (!(rules[i].val(v))))
]
fun validate(obj) =
obj pluck { v: $,k: $$ as String,i: $$$ as String } reduce ((kvp,acc={}) ->
do {
var validation = validate(kvp.v,kvp.k,kvp.i)
---
{
(acc - "Errors"),(kvp.k): kvp.v,("Errors": (acc.Errors default []) ++
(if (sizeOf(validation) > 0) validation else [])
) if(acc.Errors? or sizeOf(validation) > 0)
}
}
)
---
payload map validate($)
输出:
[
{
"Column A": "value of Column A","Column B": "value of Column B"
},{
"Column A": "","Column B": "value of Column B","Errors": [
"Invalid value for Column A: ''"
]
},{
"Column A": "value of Column A","Column B": "value of Column C","Errors": [
"Invalid value for Column B: 'value of Column C'"
]
},{
"Column A": null,"Column C": "value of Column D","Errors": [
"Invalid value for Column A: 'null'","Invalid column name: 'Column C' should be 'Column B'","Invalid value for Column B: 'value of Column D'"
]
}
]