Am trying to parse an input XML payload and transform and generate a response XML. Here is my input XML
<?xml version='1.0' encoding='UTF-8'?>
<EmployeesInfo>
<EmployeeDetails>
<Emp>a</Emp>
<Emp>b</Emp>
<Emp>c</Emp>
<Emp>d</Emp>
</EmployeeDetails>
<AddressDetails>
<city>Munich</city>
</AddressDetails>
</EmployeesInfo>
EmployeeDetails
element is optional , may be present in incoming payload , may not be present . It may contain Emp
child elements or may not contain child Emp
elements
My desired output XML is :
<?xml version='1.0' encoding='UTF-8'?>
<EmployeesInfo>
<EmployeeDetails>
<Emp>a</Emp>
<Emp>b</Emp>
<Emp>c</Emp>
<Emp>d</Emp>
</EmployeeDetails>
...
...
other XML elements
</EmployeesInfo>
I am running into errors when trying to extract EmployeeDetails
and Emp
here are two versions of code that both work in Dataweave playground but both fail when running in Anypoint studio ( 7.16 ) Mule runtime 4.6.1 EE
Version 1 using Descendants Selector:
%dw 2.0
output application/xml skipNullOn = "everywhere", inlineCloseOn = ""
---
{
EmployeesInfo: {
(EmployeeDetails: {
((payload.EmployeesInfo.EmployeeDetails.. default []) map ((item) -> {
"Emp" : item
}))
}) if (payload.EmployeesInfo.EmployeeDetails?)
}
}
This works fine when Emp
elements are present but fails when no Emp
elements are present with the error :
You called the function 'Descendants Selector ..' with these arguments:
1: Null (null)
But it expects one of these combinations:
(Array)
(Object)
103| ((payload.EmployeesInfo.EmployeeDetails.. default []) map ((item, index) -> {
Also tried with MultiValue selector :
%dw 2.0
output application/xml skipNullOn = "everywhere", inlineCloseOn = ""
---
{
EmployeesInfo: {
(EmployeeDetails: {
((payload.EmployeesInfo.EmployeeDetails.*Emp default []) map ((item) -> {
"Emp" : item
}))
}) if (payload.EmployeesInfo.EmployeeDetails?)
}
}
This too fails when Emp
is not present with similar error as above ..
NOTE: Both these versions of code work fine in Dataweave playground in browser , it is in actual runtime in anypoint studio that things are failing ......
How do I solve this ?
So found a way to work around this by checking if the element is present and only then applying :
First check if EmployeeDetails
is present
Second check before we apply Descendants selector ( this is required otherwise Descendant selector check throws error stated if there are no child elements )
This checks if EmployeeDetails
has any child elements
{
(EmployeesInfo:{
(EmployeeDetails:(payload.EmployeesInfo.EmployeeDetails.. )) if (!isEmpty(payload.EmployeesInfo.EmployeeDetails) )
})if (payload.EmployeesInfo.EmployeeDetails?)
}