JSON 数组迭代 - Mulesoft 中的树遍历

JSON Array Iteration - Tree Traversing in Mulesoft

输入JSON:

{
    "id": "/",
    "code": "/",
    "typeCode": "CPC",
    "timeStamp": "2021-11-16T17:00:00-06:00",
    "childList": [
        {
            "id": "577-1-1",
            "code": "1111",
            "name": "Electronics-1-1",
            "displayName": "Electronics-1-1",
            "active": true,
            "languageCode": "en",
            "typeCode": "CPC",
            "childList": [
                {
                    "id": "579-2-1",
                    "code": "2222",
                    "name": "Calculators-2-1",
                    "displayName": "Calculators-2-1",
                    "active": true,
                    "languageCode": "en",
                    "typeCode": "CPC",
                    "childList": []
                },
                {
                    "id": "509-2-2",
                    "code": "3333",
                    "name": "Oven-2-2",
                    "displayName": "Oven-2-2",
                    "active": true,
                    "languageCode": "en",
                    "typeCode": "CPC",
                    "childList": [
                        {
                            "id": "749-3-1",
                            "code": "4444",
                            "name": "MicroOven-3-1",
                            "displayName": "MicroOven-3-1",
                            "active": true,
                            "languageCode": "en",
                            "typeCode": "CPC",
                            "childList": []
                        }
                    ]
                }
            ]
        },
        {
            "id": "549-1-2",
            "code": "5555",
            "name": "Refrigerator-1-2",
            "displayName": "Refrigerator-1-2",
            "active": true,
            "languageCode": "en",
            "typeCode": "CPC",
            "childList": []
        }
    ]
}
  1. 而预期的 XML 如下 - 这里必须注意 categoryPath 以获取 childElement 的完整地址,并且必须分组在第一个父 childList
  2. 我们不知道任何数组的确切子元素,即 childList 中可以有“n”个 childList
  3. 如果 childList 元素是空数组 - 我们需要映射到 xml 并停止。否则在该数组内继续并为那些子元素做映射

XML 转换:

<Category CategoryId="${childList.id}" CategoryPath="${childList.code}/${childList.childList.code}" Description="${childList.name}" ShortDescription="${childList.displayName}">
    <Extn ExtnSyncTS="${headers.timeStamp}"/>
</Category>

预期 XML:

<CategoryListArray>
    <CategoryList>
      <Category CategoryId="577-1-1" CategoryPath="1111" Description="Electronics-1-1" ShortDescription="Electronics-1-1">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
      </Category>
      <Category CategoryId="579-2-1" CategoryPath="1111/2222" Description="Calculators-2-1" ShortDescription="Calculators-2-1">
        <Extn ExtnSyncTS=" "/>
      </Category>
      <Category CategoryId="509-2-2" CategoryPath="1111/3333" Description="Oven-2-2" ShortDescription="Oven-2-2">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
      </Category>
      <Category CategoryId="749-3-1" CategoryPath="1111/3333/4444" Description="MicroOven-3-1" ShortDescription="MicroOven-3-1">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
      </Category>
</CategoryList>
<CategoryList>
      <Category CategoryId="549-1-2" CategoryPath="5555" Description="Refrigerator-3-1" ShortDescription="Refrigerator-3-1">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
      </Category>
    </CategoryList>
</CategoryListArray>

您可以使用按类型匹配的递归函数来横切子树,因此它知道如何横切。然后您需要将当前节点连接到它的子节点,以便它们在输出中处于同一级别。对于数组,您应该使用 flatMap() 来避免嵌套数组。最后,XML 输出不支持数组,因此您需要将数组转换为对象。为此我使用了 reduce()。

%dw 2.0
output application/xml
fun mapChildren(x, timestamp, path)=
    x match {
        case o is Object -> 
            ([{
                Category @(CategoryId: o.id, CategoryPath: (if (isEmpty(path)) "" else path ++ "/") ++ o.code, Description: o.name, ShortDescription: o.displayName ): {Extn: timestamp}
            }] 
            ++ mapChildren(o.childList, timestamp, (if (isEmpty(path)) "" else path ++ "/") ++ o.code)) 
           
        case a is Array -> 
            (a flatMap mapChildren($, timestamp, path) )
               
        else -> $
    }
---
{
    CategoryList: 
        mapChildren(payload.childList, payload.timeStamp, "") 
        reduce ((item, accumulator={}) -> accumulator ++ item )
}

你可以把它封装成一个函数。