JSON 数组 mule 4 dataweave 中的迭代

Iteration in JSON array mule 4 dataweave

{
  "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": null
        },
        {
          "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": null
            }
          ]
        }
      ]
    },
    {
      "id": "549-1-2",
      "code": "5555",
      "name": "Toys, Crafts & Leisure",
      "displayName": "Toys, Crafts & Leisure",
      "active": true,
      "languageCode": "en",
      "typeCode": "CPC",
      "childList": [
        {
          "id": "49674",
          "code": "7605",
          "name": "Pet Supplies",
          "displayName": "Pet Supplies",
          "active": true,
          "languageCode": "en",
          "typeCode": "CPC",
          "childList": [
            {
              "id": "49684",
              "code": "7615",
              "name": "Beds & Houses",
              "displayName": "Beds & Houses",
              "active": true,
              "languageCode": "en",
              "typeCode": "CPC",
              "childList": [
                
              ]
            }
          ]
        }
      ]
    },
    {
      "id": "58782",
      "code": "0100",
      "name": "Fashion (new)",
      "displayName": "Fashion",
      "active": true,
      "languageCode": "en",
      "typeCode": "CPC",
      "childList": [
        {
          "id": "49056",
          "code": "6958",
          "name": "Blazers & Jackets, Etc. - Department",
          "displayName": "Blazers & Jackets, Etc.",
          "active": true,
          "languageCode": "en",
          "typeCode": "CPC",
          "childList": [
            {
              "id": "50851",
              "code": "7837",
              "name": "Dusters PDM Name",
              "displayName": "Dusters PDM Display Name",
              "active": true,
              "languageCode": "en",
              "typeCode": "CPC",
              "childList": null
            }
          ]
        }
      ]
    }
  ]
}

并且预期的 XML 如下 - 这里必须注意 categoryPath 以获取 childElement 的完整地址,并且必须分组在第一个父 childList 下 我们不知道任何数组的确切子元素,即 childList 中可以有“n”个 childList。 (当 childList 值为空数组 [] 或 null 时,它被视为该 childList 没有子元素。) 第一个子列表数组中存在多少个元素 - 必须在 xml 中形成那么多 CategoryList 元素 注意:这里我仅以 2 个元素为例 - 但任何子列表数组都可以在其中包含任意数量的子列表数组。

XML 转换:

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

预期 XML:

<CategoryListArray>
<CategoryList>
    <Category CategoryId="1111" CategoryPath="/DefaultText/1111" Description="Electronics-1-1" ShortDescription="Electronics-1-1">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
    <Category CategoryId="2222" CategoryPath="/DefaultText/1111/2222" Description="Calculators-2-1" ShortDescription="Calculators-2-1">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
    <Category CategoryId="3333" CategoryPath="/DefaultText/1111/3333" Description="Oven-2-2" ShortDescription="Oven-2-2">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
    <Category CategoryId="4444" CategoryPath="/DefaultText/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="5555" CategoryPath="/DefaultText/5555" Description="Toys, Crafts & Leisure" ShortDescription="Toys, Crafts & Leisure">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
    <Category CategoryId="7605" CategoryPath="/DefaultText/5555/7605" Description="Pet Supplies" ShortDescription="Pet Supplies">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
    <Category CategoryId="7615" CategoryPath="/DefaultText/5555/7605/7615" Description="Beds & Houses" ShortDescription="Beds & Houses">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
</CategoryList>
<CategoryList>
    <Category CategoryId="0100" CategoryPath="/DefaultText/0100" Description="Fashion" ShortDescription="Fashion (new)">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
    <Category CategoryId="6958" CategoryPath="/DefaultText/0100/6958" Description="Blazers & Jackets, Etc." ShortDescription="Blazers & Jackets, Etc. - Department">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
    <Category CategoryId="7837" CategoryPath="/DefaultText/0100/6958/7837" Description="Dusters PDM Display Name" ShortDescription="Dusters PDM Name">
        <Extn ExtnSyncTS="2021-11-16T17:00:00-06:00"/>
    </Category>
</CategoryList>
</CategoryListArray>

我已经使用递归创建了一个解决方案。可能有点乱,我已经在DW里面的评论里解释了。

%dw 2.0
var extnSyncTs = payload.timeStamp

// This is just a small utility function to generate the "CategoryPath"
fun appendToPath(currentPath, pathToAppend) = 
    if(isEmpty(currentPath)) pathToAppend
    else currentPath ++ "/" ++ pathToAppend

/*
* This function will take one object from the child list array 
* and return corresponding XML Category object  
*/
fun childListElementToCategory(childListElement, rootPath='') = 
    {
        Category @(
            CategoryId: childListElement.code,
            CategoryPath: rootPath appendToPath childListElement.code,
            Description: childListElement.displayName,
            ShortDescription: childListElement.name
        ): {
            Extn @(ExtnSyncTS: extnSyncTs): null
        }
    }

/**
* This is a tricky one. It accepts the childList array then uses the above
* function to get the Category element for each of the chileList element. It 
* uses recurssion to call itself if there are more childList in any element 
* of the passed childList. The rootPath element is to retain the path from 
* the parent childList element. 
*/

fun childListToCategoryList(childList, rootPath='') = 
    childList map ((childListElement) -> 
        {
            (childListElementToCategory(childListElement, rootPath)),
            (childListToCategoryList(childListElement.childList, rootPath appendToPath childListElement.code)) 
        }
    )
output application/xml
---
CategoryListArray: {
    CategoryList: (childListToCategoryList(payload.childList))
}