gtx911
gtx911

Reputation: 1289

Dataweave - Loop in-depth mapping XML

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:

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?

Upvotes: 2

Views: 2173

Answers (2)

Shoki
Shoki

Reputation: 1538

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)

Upvotes: 4

machaval
machaval

Reputation: 5059

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

Upvotes: 3

Related Questions