xmlxqueryexist-db

Trying to perform a cartesian product on two XML files using XQuery


I'm trying to work with XML datasets, and I'm having a hard time trying to understand how to perform iterations and join operations with XQuery.

I have these two XML tables:

employees.xml:

<employees>
    
    <employee cod="E01" dept="D01">
        <name>John</name>
        <middle-name>S.</middle-name>
        <lastname>Gladstone</lastname>
    </employee>
    
    <employee cod="E02" dept="D01">
        <name>Ana</name>
        <lastname>Ferraz</lastname>
    </employee>

</employees>

and departments.xml:

<departments>

    <department cod="D01">
        <name>Sales</name>
        <local>3rd floor</local>
    </department>
    
    <department cod="D02">
        <name>Finances</name>
        <local>4th floor</local>
    </department>
    
</departments>

I want to perform a join operation on this data, resulting in something like this:

<result>
    <dep-emp>
        <department>Sales</department>
        <employee>John</employee>
    </dep-emp>
    
    <dep-emp>
        <department>Sales</department>
        <employee>Ana</employee>
    </dep-emp>
    
    <dep-emp>
        <department>Finances</department>
        <employee>John</employee>
    </dep-emp>
    
    <dep-emp>
        <department>Finances</department>
        <employee>Ana</employee>
    </dep-emp>
</result>

I have tried to use a "for" statement with no success. Can someone please help me?


Solution

  • This is a pretty straight forward embedded loop:

    xquery version "3.0";
    
    let $employees := <employees>
        <employee cod="E01" dept="D01">
            <name>John</name>
            <middle-name>S.</middle-name>
            <lastname>Gladstone</lastname>
        </employee>
        <employee cod="E02" dept="D01">
            <name>Ana</name>
            <lastname>Ferraz</lastname>
        </employee>
    </employees>
    
    let $departments := <departments>
        <department cod="D01">
            <name>Sales</name>
            <local>3rd floor</local>
        </department>
        
        <department cod="D02">
            <name>Finances</name>
            <local>4th floor</local>
        </department>
    </departments>
    
    return <result>{
        for $dep in $departments/department
            for $emp in $employees/employee[@dept eq $dep/@cod]
                return <dep-emp>
                    <department>{string($dep/name)}</department>
                    <employee>{string($emp/name)}</employee>
                </dep-emp>
    }</result>