muledataweavemule-studiomule4anypoint-studio

Trying to parse XML payload but getting an error : You called the function 'Descendants Selector ..' with these arguments: 1: String ("")


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 ?


Solution

  • 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?)
    }