Ned_Kelly
Ned_Kelly

Reputation: 69

XQuery combine two xml files

Currently have two XML files and want to combine them to create 1 XML file.

XML 1 (recipes.xml):

<recipes>
    <recipe id="182">
        <name>Hamburger</name>
        <description>Hamburgers are created...</description>
        <chapter>1</chapter>
        <page_number>13</page_number>
    </recipe>
    <recipe id="185">
        <name>Muffins</name>
        <description>Muffins picked with...</description>
        <chapter>2</chapter>
        <page_number>43</page_number>
    </recipe>
<recipes>

XML 2 (ingredients.xml):

<ingredients>
    <ingredient id="5">
        <name>Burger Buns</name>
        <recipe_id>182</recipe_id>
        <price>$3.00</price>
        <quantity>13</quantity>
    </ingredient>
    <ingredient id ="111">
        <name>Carrot</name>
        <recipe_id>182</recipe_id>
        <price>2.50</price>
        <quantity>1</quantity>
    </ingredient>
    <ingredient id ="535">
        <name>Blueberry</name>
        <recipe_id>185</recipe_id>
        <price>$5.00</price>
        <quantity>1 Packet of 200 grams</quantity>
    </ingredient>
<ingredients>

And I want them to combine to that the recipes have the ingredients like this: Output:

<food>
    <recipe id ="182">
        <name>Hamburger</name>
        <description>Hamburgers are created...</description>
        <chapter>1</chapter>
        <page_number>13</page_number>
            <ingredient id ="5">
                <name>Burger Buns</name>
                <price>$3.00</price>
                <quantity>13</quantity>
            </ingredient>
            <ingredient id ="111">
                <name>Carrot</name>
                <price>$2.50</price>
                <quantity>1</quantity>
            </ingredient>
    </recipe>
    <recipe id ="185">
        <name>Muffins</name>
        <description>Muffins picked with...</description>
        <chapter>2</chapter>
        <page_number>43</page_number>
            <ingredient id ="535">
                <name>Blueberry</name>
                <price>$5.00</price>
                <quantity>1 Packet of 200 grams</quantity>
            </ingredient>
    </recipe>
</food>

Currently trying to do the merge in a program called BaseX. I can do simple queries using a single for loop but having troubles putting 2 separate documents together.

Upvotes: 0

Views: 1183

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167446

You can just select the elements from the other document that match on the id and then fill them in:

<food>
{
    for $recipe in recipes/recipe
    let $ingredients := $doc2/ingredients/ingredient[$recipe/@id = recipe_id]
    return
        <recipe>
            {
                $recipe/(@*, *),
                $ingredients/<ingredient>{@*, * except recipe_id }</ingredient>
            }
        </recipe>
}
</food>

The other document you can read in as an external variable or use doc('ingredients.xml'), full example with external variable (defaulting for compactness of the example to inline XML) is at https://xqueryfiddle.liberty-development.net/6qM2e2j

Upvotes: 1

Related Questions