Dataweave : Transform XML to JSON - mule

Using Mule 4.4 community edition and am using Dataweave to perform transformation.
Payload is in XML as below :
<Result>
<TRNO>abcd</TRNO>
<EMPS>
<EMP>
<NAME>JOHN</NAME>
<AGE>21</AGE>
</EMP>
<EMP>
<NAME>TOM</NAME>
<AGE>18</AGE>
</EMP>
</EMPS>
</Result>
I need JSON as below:
{
"trackId": "abcd",
"empDetails": [
{
"empName": "JOHN",
"empAge": "21"
},
{
"empName": "TOM",
"empAge": "18"
}
]
}
I am trying to generate using following dataweave but its erroring out :
%dw 2.0
output application/json writeAttributes=true
---
if (payload.Result.EMPS.EMP?)
"trackId": payload.Result.TRNO,
empDetails:payload.Result.EMPS.*EMP map {
empName: $.NAME,
empAge: $.AGE
}
else
null
It does not like this line "trackId": payload.Result.TRNO, before the array population.
The error is :
Invalid input ',', expected FieldName (line 5, column 35):
5| "trackId": payload.Result.TRNO,
^ Location: main (line: 5, column:35)

Just give braces enclosing your if , should be good.
%dw 2.0
output application/json writeAttributes=true
---
if (payload.Result.EMPS.EMP?)
{
"trackId": payload.Result.TRNO,
empDetails: payload.Result.EMPS.*EMP map {
empName: $.NAME,
empAge: $.AGE
}
}
else
null

Related

dataweave script to iterate over a nested array of string literals

So I have the following payload :
<?xml version="1.0" encoding="utf8" ?>
<Output>
<Error>
<Status>0</Status>
<Details>No errors</Details>
</Error>
<Synopsis>
<Count>451</Count>
</Synopsis>
<BankAccounts>
<BankAccount AcctNo="103" CustName="Frank" BalanceAmount="" Inactive="N" NoOfAccounts="1" >
<Addresses>
<Address>ABC</Address>
<Address>XYZ</Address>
</Addresses>
</BankAccount>
<BankAccount AcctNo="101" CustName="Jane" BalanceAmount="10005" Inactive="N" NoOfAccounts="1" >
<Addresses>
<Address>LMN</Address>
<Address>QWE</Address>
</Addresses>
</BankAccount>
</BankAccounts>
</Output>
I need to convert it into the following json :
[
{
"accountNumber": "103",
"customerName": "Frank",
"balanceAmount": "",
"inactive": "N",
"noOfAccounts": "1",
"address": [
"ABC","XYZ"
]
},
{
"accountNumber": "101",
"customerName": "Jane",
"balanceAmount": "10005",
"inactive": "N",
"noOfAccounts": "1",
"address": [
"LMN","QWE"
]
}
]
I am nearly there using the below dataweave script:
%dw 2.0
output application/json writeAttributes=true
---
payload.Output.BankAccounts.*BankAccount map {
accountNumber: $.#AcctNo,
customerName: $.#CustName,
balanceAmount: $.#BalanceAmount,
inactive: $.#Inactive,
noOfAccounts: $.#NoOfAccounts,
address: $.Addresses.*Address map (value,index)->{
}
}
However I have not been able to convert the Addresses element ( which contains multiple Address elements into a string array like this :
"address": [
"LMN","QWE"
]
Am struggling with the last part , any ideas ?
Note that XML does not has the concept of an array. Addresses is just an element that has several address child elements.
You can use the multivalued selector directly. It will return an array of the matching keys values. Map is only needed if you want to further transform each element.
$.Addresses.*Address
You can use the value from the address array without using {}. DW creates an object when curly braces are used.
%dw 2.0
output application/json
---
payload.Output.BankAccounts.*BankAccount map ((account) -> {
accountNumber: account.#AcctNo,
customerName: account.#CustName,
balanceAmount: account.#BalanceAmount,
inactive: account.#Inactive,
noOfAccounts: account.#NoOfAccounts,
address: account.Addresses.*Address map ((value)-> value)
})

How to convert CSV to JSON in mule 4

Is there easy way to convert CSV into JSON in mule 4? Currently I'm doing it as below.
%dw 2.0
output application/json
---
(payload splitBy('\r\n')) map using( tmp = $ splitBy(',')) {
id : tmp[0],
name: tmp[1]
}
Try with following
%dw 2.0
output application/json
---
payload
Input :-
id,name
2,Tom
3,Jerry
And output produced is
[
{
"id": "2",
"name": "Tom"
},
{
"id": "3",
"name": "Jerry"
}
]
Hope this helps.
Best working solution, if you have a CSV with comma separated values and a first row with header is:
FIRST TRANSFORM MESSAGE
%dw 2.0
output application/csv headerLineNumber=0, header=true
---
payload
SECOND TRANSFORM MESSAGE
%dw 2.0
output application/dw
---
payload
Try following in Transform message
%dw 2.0
output application/json
payload map {
FirstName: $.FirstName,
LastName : $.LastName,
Department : $.Department,
Email : $.Email,
Phone : $.Phone,
CreatedDate : $.CreatedDate
}

Mulesoft Dataweave Converting the key of a mapObject to lower case

Assume the following json with KEY1 and KEY2 in caps. KEY1 and KEY2 needs to be converted to lower case
{
"KEY1": {
"subkey1": "subval1",
"subkey2": "subval2"
},
"KEY2": {
"subkey1": "subval1",
"subkey2": "subval2"
}
}
this needs to be converted to the following json using data weave.
{
"key1": {
"subkey1": "subval1",
"subkey2": "subval2"
},
"key2": {
"subkey1": "subval1",
"subkey2": "subval2"
}
}
I tried the following DW syntax, but it did not work
result : payload mapObject (
lower '$$':$
)
The DW you tried should work if you wrap the expression in parenthesis. This ensures that the lower operator is applied to each of the keys first and then that value is used in the map. So for your example:
%dw 1.0
%output application/json
---
{
result : payload mapObject (
(lower '$$') : $
)
}
Interestingly enough, I get an error (mismatched input ':' expecting ')') in my Transform Message using this DW syntax but I am able to run the project without complaints from Anypoint Studio and the DW runs fine. It also works in MEL with the following:
#[dw("{result : payload mapObject ( (lower '$$' ) : $)}", 'application/json')]
Hope that helps!
You can use the below method to resolve the issue.
%dw 2.0
output application/json
---
{ result: payload mapObject (
(lower ('$$')): $
)
}
In addition if need to lower case also a values then its will be like:
%dw 1.0
%output application/json
---
{
result : payload mapObject (
(lower $$) : (lower $)
)
}

mule : how to convert list of maps to list of JSon in dataweave?

I have input data as list of maps like [{id="200" name="aaa"},{id="100",name="shbd"}].
I want to transform it to JSON like below
{
[
{
id="200",
name="aaa"
},
{
id="100",
name="shbd"
}
]
}
If the fields(keys in map) do no change, then it is simple and straightforward. Now how to transform if I dont know the key values. For eg, what if after sometime the input of map is [{"age":90},{"age","45"}]
It's always better to do specific mapping but you can go with the following , it will transform it into JSON
%dw 1.0
%output application/json
---
payload
As Anirban said, please validate the json you want to transform.
You can use below transformation for o/p specified below:
Transformation
---------------
%dw 1.0
%output application/json
---
payload map {
"id" : $.id,
"name" : $.name
}
---------------
expected output
--------------
[
{
id="200",
name="aaa"
},
{
id="100",
name="shbd"
}
]

Create json array using dataweave

If I have xml like so....
<Root>
<Authority>Water</Authority>
<Sanctions>
<Sanction>
<SanctionCode>11</SanctionCode>
<SanctionDesc>First Sanction</SanctionDesc>
</Sanction>
<Sanction>
<SanctionCode>11</SanctionCode>
<SanctionDesc>Second Sanction</SanctionDesc>
</Sanction>
</Sanctions>
</Root>
Using DataWeave how can I create a json array of Santions using only the SanctionDesc?
I've tried this but it's not right...
%dw 1.0
%output application/json
---
records: payload.Root map {
Authority: $.Authority,
sanctions: $.Sanctions.Sanction map [$.SanctionDesc]
}
I want my output to look like this...
{
"records": [{
"Authority": "Water",
"sanctions": ["First Sanction", "Second Sanction"]
}]
}
Try this
%dw 1.0
%output application/json
---
records: {
Authority: payload.Root.Authority,
sanctions: payload.Root.Sanctions..SanctionDesc
}
Or
%dw 1.0
%output application/json
---
records: {
Authority: payload.Root.Authority,
sanctions: payload.Root.Sanctions.*Sanction map $.SanctionDesc
}
Hope this helps.
Understading the map operator is the key when picking and choosing elements from input payload. Map operator goes through all the array elements on the left hand side and we can pick the values from on right hand side, Giving example from Mulesoft portal
%dw 1.0
%output application/json
users: ["john", "peter", "matt"] map ((firstName, position) -> position ++ ":" ++ upper firstName)
Output:
{
"users": [
"0:JOHN",
"1:PETER",
"2:MATT"
]
}
See link below:
https://docs.mulesoft.com/mule-user-guide/v/3.8/dataweave-operators#map