2
votes

I have a XML payload that contains the following example:

<Example>
    <Brand>
        <Id>987S</Id>
        <logo>circle</logo>
        <Item>
            <Name>cologne1</Name>
            <Item>
                <Name>Bosque</Name>
            </Item>
        </Item>
        <Item>
            <Name>t-Shirt</Name>
        </Item>
    </Brand>
    <Brand>
        <Id>877823C</Id>
        <logo>circle</logo>
        <Item>
            <Name>t-Shirt2</Name>
            <Item>
                <Name>t-Shirt black</Name>
                <Item>
                    <Name>t-Shirt black with logo</Name>
                </Item>
            </Item>
        </Item>
    </Brand>
</Example>

The XML is divided into:

  • Example as root node
    • Brand Objects
      • Item Objects: Those Items can also contains more Items

I get this structure randomly until 3 levels in-depth per Item.

The output expected is all Items in the same level into a parent node:

<Supermarket>
    <Item>
        <BarValue>cologne1</BarValue>
    </Item>
    <Item>
        <BarValue>Bosque</BarValue>
    </Item>
    <Item>
        <BarValue>t-Shirt</BarValue>
    </Item>
    <Item>
        <BarValue>t-Shirt2</BarValue>
    </Item>
    <Item>
        <BarValue>t-Shirt black</BarValue>
    </Item>
    <Item>
        <BarValue>t-Shirt black with logo</BarValue>
    </Item>
</Supermarket>

Is there a way to loop the XML file dynamically with Dataweave?

2
What would you want to do with the items? - Shoki
@Shoki map and transform each item to another kind of object and store in a file - gtx911

2 Answers

3
votes

Some ways to do this:

%dw 2.0
output application/xml
---
{
    Supermarket: {(
        payload..*Item map {
            Item: {
                BarValue: $.Name
            }
        }
    )}
}

The descendants selector payload..Item gets all the Items in any level. Then for each Item we generate an object with {Item: {BarValue: $.Name}} and get an Array of item objects.

The problem is that the XML model in DataWeave represents element tags and values with Objects and Strings, there is no concept of Array (which was our result of items).

So we use the Dynamic Object feature {(expr)} where expr returns an Array of key value pairs that are expanded into key-value pairs of the object.

Alternative:

%dw 2.0
output application/xml
---
{
    Supermarket: {
        Item: {
            BarValue: payload..*Item.Name
        }
    }
}

This last one works because in XML when the writer tries to write an Array, it repeats the Key (Item) that contains said Array (payload..Item.Name)

3
votes

If you want to collect all the Item elements you can use the descendant selector.

%dw 2.0
output application/json
---
payload..Item

If this is not what you want please provide an expected output and we can help more