如何在不使用 Dataweave 中的列名的情况下创建 Excel 文件 key-value 的映射?

How to create a map of Excel file key-value without using column name in Dataweave?

我正在将 excel 文件 (.xlsx) 读取到 json 数组中,并且正在创建地图,因为我想分别对每一列应用验证。我可以像这样使用列名访问它, Excel 文件是:

column A,          column B
value of Column A, value of column B

我是这样访问它的: 有效负载映射(项目,索引)-> "列名 A" : item."列名 A", “列名 B”:项目。“列名 B”

其中 A 列和 B 列是 excel 列 header。

我想做的是创建相同的地图,但使用像

这样的列索引
payload map(item, index) ->
        item[0].key : item[0],
        item[1].key : item[1]

这样我就不必硬编码 excel header 名称,我可以依赖 excel 列的索引。

我曾尝试使用 pluck $$ 创建键的映射,但我无法创建 keys-value 的映射,我无法使用项目 [0] 作为映射中的键。

如何在不使用 excel 列 header 名称的情况下实现上述目标?

预期的输出应该是这样的:

{ 
  "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",
    "col2": "val1.2",
    "col3": "val1.3",
    "Errors": [
      
    ]
  },
  {
    "col1": "val2.1",
    "col2": "val2.2",
    "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'"
    ]
  }
]