Search code examples
muledataweavemule4

Dataweave: Filter XML payload based on staring value starting with specific character


I have an input XML which has a list of suppliers and some other data. The input XML looks like:

             <screenFields>
                <ScreenFieldDTO>
                    <fieldName>SUPP1</fieldName>
                    <value>123</value>
                </ScreenFieldDTO>
                <ScreenFieldDTO>
                    <fieldName>MAKE1</fieldName>
                    <value>ABC</value>
                </ScreenFieldDTO>
                <ScreenFieldDTO>
                    <fieldName>SUPP2</fieldName>
                    <value>234</value>
                </ScreenFieldDTO>
                <ScreenFieldDTO>
                    <fieldName>NORM2</fieldName>
                    <value>TXT2</value>
                </ScreenFieldDTO>
                <ScreenFieldDTO>
                    <fieldName>SUPP3</fieldName>
                    <value>124</value>
                </ScreenFieldDTO>
                </screenFields>

I want to filter this XML to access the values of field names which start with 'SUPP'. I know the filter in dataweave can compare the entire value but I need to filter field names containing specific string.

The mapping looks like:

 %dw 2.0
 output application/json
 fun filterSupplier(val) = if(val startsWith("SUPP")) "SUPP" else ""
 ---
{
"fieldname": payload.screenFields.*ScreenFieldDTO filter $.fieldName == 
 (filterSupplier($.fieldName))
}

The expected response is:

{
 [
  {"fieldname" : "SUPP1", "value": "123"},
  {"fieldname" : "SUPP2", "value": "234"},
  {"fieldname" : "SUPP3", "value": "124"}
 ]
}

The response is coming as blank. What is wrong with this code?


Solution

  • The script that you are using is overly complicated for the filter. filter() just requires an expression that returns true or false, so simply filter ($.fieldName startsWith("SUPP")) will work and expresses the intention much more clearly.

    I'm assuming that the expected output is an array. I would also added a map to change the key name in each element of the array to fieldname as in the expected output.

    %dw 2.0
    output application/json
    ---
    payload.screenFields.*ScreenFieldDTO 
        filter ($.fieldName startsWith("SUPP"))
        map {"fieldname": $.fieldName }
    

    Output:

    [
      {
        "fieldname": "SUPP1"
      },
      {
        "fieldname": "SUPP2"
      },
      {
        "fieldname": "SUPP3"
      }
    ]