如何将 JSON 数组展平为 csv 文件

Cou*_*xer 0 mule dataweave mulesoft

我有一个 JSON 格式的传入有效负载,我将其中的一些对象输出到 CSV 文件。有效载荷也有一个数组:

      "Chargebacks": [
        {
          "CostCenterCode": "123ABC",
          "AllocationPercentage": 100
        },
        {
            "CostCenterCode": "456DEF",
            "AllocationPercentage": 100
        }
      ]
Run Code Online (Sandbox Code Playgroud)

我需要 CSV 文件包含:

<other headers from the objects>,Cost Center Code 1, Allocation Percentage 1, Cost Center Code 2, Allocation Percentage 2
<other object values>,123ABC,100,456DEF,100
Run Code Online (Sandbox Code Playgroud)

我的第一次尝试是创建两个变量来保存标题列表和值列表:

%dw 2.0
output application/csv
var x = payload.Item.CatalogAttributes.Chargebacks map (chargeBack, index) -> 
{
    "header": "Cost Center Code " ++ index+1 ++ ", Allocation Percentage "++ index+1,
    "costCenterCode": chargeBack.CostCenterCode ++ "," ++ chargeBack.AllocationPercentage,
}
var foo = x.*header joinBy ','
var bar = x.*costCenterCode joinBy ','
---
Run Code Online (Sandbox Code Playgroud)

并将它们添加到文件末尾:

foo: bar
Run Code Online (Sandbox Code Playgroud)

它有点工作。我在标题123ABC\,100\,456DEF\,100的末尾和值的末尾得到值“foo” 。如何获取 foo 的实际值并从值中删除斜线?

Mic*_*nes 5

我将在我的回答中假设您可能不提前知道有多少退款项目。这个数据编织:

%dw 2.0
output application/csv
---
payload map {
    ($ - "Chargebacks"),
    ($.Chargebacks map {
        ("CostCenterCode_$($$)": $.CostCenterCode),
        ("AllocationPercentage_$($$)": $.AllocationPercentage)
    })
}
Run Code Online (Sandbox Code Playgroud)

使用此示例输入:

%dw 2.0
output application/csv
---
payload map {
    ($ - "Chargebacks"),
    ($.Chargebacks map {
        ("CostCenterCode_$($$)": $.CostCenterCode),
        ("AllocationPercentage_$($$)": $.AllocationPercentage)
    })
}
Run Code Online (Sandbox Code Playgroud)

产生这个csv:

field1,field2,CostCenterCode_0,AllocationPercentage_0,CostCenterCode_1,AllocationPercentage_1
someValue,someValue,123ABC,100,456DEF,100
someValue2,someValue2,123ABC2,200,456DEF2,200
Run Code Online (Sandbox Code Playgroud)

通过将我们的地图包装在(...)我们基本上是告诉它获取结果数组并将其展平为顶级对象。如果您熟悉,这与 javascript 中的展开运算符非常相似。该$$$被简写功能。例如,如果您有一个这样的函数:fun someFun(left, fn: (item, index) -> Any),您可以使用此模式调用它payload someFun ...,其中有效负载成为参数left,然后右侧成为函数;传入函数的每个参数都变成了 a $,其中$s的个数就是参数的位置。有道理?请注意,这种调用函数的模式不仅限于采用函数的模式。例如,你可以创建一个这样的函数:fun add(left, right) = left + right并以这种方式调用它1 add 2. 这仅在使用fun关键字时有效,并且当您只有两个参数时。

如果您打算使用可能不规则的尺寸(即:有些可能比其他尺寸多)并且需要为较小的元素设置空白条目,则您需要提前确定最大尺寸并执行以下操作:

%dw 2.0
output application/csv
var maxSize = max(payload map sizeOf($.Chargebacks))
---
payload map (row) -> {
    (row - "Chargebacks"),
    ((1 to maxSize) map {
        ("CostCenterCode_$($$)"): row.Chargebacks[$$].CostCenterCode,
        ("AllocationPercentage_$($$)"): row.Chargebacks[$$].AllocationPercentage
    })
}
Run Code Online (Sandbox Code Playgroud)

这将映射这样的输入:

[
    {
        "field1": "someValue",
        "field2": "someValue",
        "Chargebacks": [
            {
                "CostCenterCode": "123ABC",
                "AllocationPercentage": 100
            },
            {
                "CostCenterCode": "456DEF",
                "AllocationPercentage": 100
            }
        ]
    },
    {
        "field1": "someValue2",
        "field2": "someValue2",
        "Chargebacks": [
            {
                "CostCenterCode": "123ABC2",
                "AllocationPercentage": 200
            },
            {
                "CostCenterCode": "456DEF2",
                "AllocationPercentage": 200
            }
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

对此:

field1,field2,CostCenterCode_0,AllocationPercentage_0,CostCenterCode_1,AllocationPercentage_1,CostCenterCode_2,AllocationPercentage_2
someValue,someValue,123ABC,100,456DEF,100,456DEF,100
someValue2,someValue2,123ABC2,200,456DEF2,200,,
Run Code Online (Sandbox Code Playgroud)