lulu
lulu

Reputation: 11

Xquery nested hierarchy

I was trying to query for a XML file

<?xml version="1.0" encoding="UTF-8"?>
<family>
    <person salary="1000">
        <name>Maria Fischer</name>
        <person salary="750">
            <name>Helmut Fischer</name>
            <person salary="830">
                <name>Maria Helbing</name>
                <person salary="0">
                    <name>David Helbing</name>
                </person>
            </person>
         </person>
    </person>
</family>

This is a hierarchy of persons in which a parent/child relationship in the XML document represents a parent/child relationship in the family. I want to query for the total sum of the salary of the whole family using XQUERY. I know somehow I have to use nested FLWOR return and fn:sum. I've tried

 for $p in doc("family.xml")/family
 return 
    for $p in $p/person
    return $p

I believe this can extract all the node in XML. But I still don't know how to extract the salary attributes and sum them up. I'm pretty new to XQUERY and haven't seen related questions on stackflow. XQuery Nested For Loop seems related but I still cannot figure it out. Please help!

Upvotes: 1

Views: 790

Answers (3)

Michael Kay
Michael Kay

Reputation: 163322

You're all over-complicating it. It's simply

sum(//@salary)

Upvotes: 3

kieraf
kieraf

Reputation: 96

It can be done using xpath only:

//family/sum(.//person/@salary)

(tested on http://xpather.com/WVyWJ27N)

Using FLWR you can do it (as already suggested) very similarly: http://xpather.com/lUYxzXfC

Upvotes: 2

C. M. Sperberg-McQueen
C. M. Sperberg-McQueen

Reputation: 25034

Nested FLWR expressions using selectors which use the child::-axis to descend the tree are never going to handle arbitrary recursion in the data. Unless your family elements have fixed or maximum depth, you don't want nested FLWR expressions (at least, not for this reason).

Try a recursive function. Or just something along the lines of

for $f in doc('family.xml')/family
return sum($f/descendant::person/@salary)

(not tested).

Upvotes: 0

Related Questions