Input 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": []
}
]
}
- And the expected XML is as below - Here the categoryPath has to be noted for the complete address of childElement
- We will not know the exact child elements of any array i.e., there can be ‘n’ number of childList inside a childList
- If childList element is empty array - we need to do mapping to xml and stop., else proceed inside that array and do the mapping for those child elements
XML Transformation:
<Category CategoryId="${childList.id}" CategoryPath="${childList.code}/${childList.childList.code}" Description="${childList.name}" ShortDescription="${childList.displayName}">
<Extn ExtnSyncTS="${headers.timeStamp}"/>
</Category>
Expected XML:
<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>
<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>
CodePudding user response:
You can transverse the child tree using a recursive function that matches by type, so it knows how to transverse. Then you need to concatenate the current node to its childrens so they are at the same level in the output. For the arrays you should use flatMap() to avoid nesting arrays. Finally the XML output doesn't support arrays so you'll need to transform the array into an object. I used reduce() for that.
%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 )
}
You could encapsulate it more into a function.