问题
I having input as Array (json) which needs to groupBy
and orderBy
with clientId
so that its internal Lines
are grouped and ordered in to one root in xml (repetitive lines of clientId). I'm stuck how to use dataweave for the XMl response. Please find the request and expected response.
Request:
[
{
"ClientId": 2,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "30",
"Quantity": "20"
},
{
"ClientId": 1,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "56",
"Quantity": "20"
},
{
"ClientId": 1,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "70",
"Quantity": "20"
}
]
Response
<?xml version='1.0' encoding='UTF-8'?>
<Receipt>
<client clientId="1">
<code>string</code>
<Lines>
<Warehouse>56</Warehouse>
<Quantity>20</Quantity>
</Lines>
<Lines>
<Warehouse>70</Warehouse>
<Quantity>20</Quantity>
</Lines>
</client>
<client clientId="2">
<code>string</code>
<Lines>
<Warehouse>30</Warehouse>
<Quantity>20</Quantity>
</Lines>
</client>
</Receipt>
Let me if question is unclear. Thanks in advance.
回答1:
Try this, comments are embedded in the code:
%dw 2.0
output application/xml
var data = [
{
"ClientId": 2,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "30",
"Quantity": "20"
},
{
"ClientId": 1,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "56",
"Quantity": "20"
},
{
"ClientId": 1,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "70",
"Quantity": "20"
}
]
---
Receipt: do {
// Group by the data
var groupedData = data groupBy $.ClientId
// Order the client Ids
var orderedClientIds = groupedData pluck $$ orderBy $ as Number
---
// Iterate over the ordered clientIds and create an object, hence the use of reduce
orderedClientIds reduce (cId, cIds={}) -> cIds ++ {
// Add the clientId attribute to the client tag
client @(clientId: cId ): {
// Get the code from the first element in the array
code: groupedData[cId][0].Code,
// Create the Lines, should you avoid repeating tags at the
// same level with other tags? i.e. code and Lines
// IMHO a best practice XML should have code, a single Lines
// and nested in Lines, one or more Line tags organizing the
// data
Lines: groupedData[cId] reduce (
(l,ls={}) -> ls ++ Lines :{
Warehouse: l.Warehouse,
Quantity: l.Quantity
}
)
}
}
}
What is still unclear to me is whether you want to order the Warehouse
and/or Quantity
values. I did not in the above code but you can easily do it, just let me know and I 'll amend.
EDIT: If you copy and paste the code in a Transform Message
processor, Studio will show an error--this error is a false positive, turn on the preview or even better stick an HTTP Listener
to the source and give it a go :)
回答2:
I hate xml. But here's my go at it. Hope it helps.
%dw 2.0
output application/json
var data = [
{
"ClientId": 2,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "30",
"Quantity": "20"
},
{
"ClientId": 1,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "56",
"Quantity": "20"
},
{
"ClientId": 1,
"Code": "string",
"ReceivedDate": "2018-10-23",
"ReceivedTime": "2217",
"Warehouse": "70",
"Quantity": "20"
}
]
var clients = (data orderBy $.ClientId groupBy $.ClientId)
---
{
Receipt: clients mapObject (v,k,i) -> {client @(clientId: k): {
code: v.Code[0]
} ++ ((v map (item,ind) -> {
Lines: {
Warehouse: item.Warehouse,
Quantity: item.Quantity
}
}) reduce (value, acc={}) -> acc ++ value)
}
}
Gives output:
<?xml version='1.0' encoding='UTF-8'?>
<Receipt>
<client clientId="1">
<code>string</code>
<Lines>
<Warehouse>56</Warehouse>
<Quantity>20</Quantity>
</Lines>
<Lines>
<Warehouse>70</Warehouse>
<Quantity>20</Quantity>
</Lines>
</client>
<client clientId="2">
<code>string</code>
<Lines>
<Warehouse>30</Warehouse>
<Quantity>20</Quantity>
</Lines>
</client>
</Receipt>
来源:https://stackoverflow.com/questions/61836535/how-to-use-groupby-with-orderby-on-array-to-xml-in-mule4