How to use groupBy with orderBy on Array to XMl in Mule4

…衆ロ難τιáo~ 提交于 2020-12-16 03:38:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!