Reputation: 55
I have a xml containing books at a library. I want to list all the books that arent checked out. So m approach is to get all the books and if the book id matches a checked out book id do not list it, otherwise list it.
In java or another language I would do a double for loop and loop over the elements is there something similar with xQuery?
<book asin="0201100886" created="128135928" lastLookupTime="128135928">
<uuid>BA57A934-6CDC-11D9-830B-000393D3DE16</uuid>
<title>Compilers</title>
<authors>
<author>Alfred V. Aho</author>
<author>Ravi Sethi</author>
<author>Jeffrey D. Ullman</author>
</authors>
<publisher>Addison Wesley</publisher>
<published>1986-01-01</published>
<price>102.00</price>
<purchaseDate>2005-01-22</purchaseDate>
</book>
<borrowers>
<borrower id="1">
<name> John Doe </name>
<phone> 555-1212 </phone>
<borrowed>
<book asin="0138613370"/>
<book asin="0122513363"/>
</borrowed>
</borrower>
</borrowers>
Upvotes: 2
Views: 26644
Reputation: 163458
Assuming the <book>
and <borrower>
elements are children of a <library>
element (to make the XML well formed), it's just
/library/book[not(@asin = /library/borrowers/borrower/book/@asin)]
Upvotes: 2
Reputation: 52878
In java or another language I would do a double for loop and loop over the elements is there something similar with xQuery?
XQuery also has a "for" loop/clause.
Here are a couple of examples.
The first example is if the <book>
and <borrowers>
are in different files:
books.xml
(Notice that the second book has an asin
that matches an asin
in the borrowers.xml file.)
<books>
<book asin="0201100886" created="128135928" lastLookupTime="128135928">
<uuid>BA57A934-6CDC-11D9-830B-000393D3DE16</uuid>
<title>Compilers</title>
<authors>
<author>Alfred V. Aho</author>
<author>Ravi Sethi</author>
<author>Jeffrey D. Ullman</author>
</authors>
<publisher>Addison Wesley</publisher>
<published>1986-01-01</published>
<price>102.00</price>
<purchaseDate>2005-01-22</purchaseDate>
</book>
<book asin="DEVNULL" created="128135928" lastLookupTime="128135928">
<uuid>98374982739847298347928374</uuid>
<title>Test Book</title>
<authors>
<author>DevNull</author>
</authors>
<publisher>Stackoverflow</publisher>
<published>2011-04-29</published>
<price>FREE</price>
<purchaseDate>2011-04-29</purchaseDate>
</book>
</books>
borrowers.xml
<borrowers>
<borrower id="1">
<name> John Doe </name>
<phone> 555-1212 </phone>
<borrowed>
<book asin="0138613370"/>
<book asin="0122513363"/>
<book asin="DEVNULL"/>
</borrowed>
</borrower>
</borrowers>
XQuery
<availableBooks>
{
let $borrowed := doc("borrowers.xml")/borrowers/borrower/borrowed/book
for $book in doc("books.xml")/books/book
where not($borrowed[@asin = $book/@asin])
return $book
}
</availableBooks>
Results
<availableBooks>
<book asin="0201100886" created="128135928" lastLookupTime="128135928">
<uuid>BA57A934-6CDC-11D9-830B-000393D3DE16</uuid>
<title>Compilers</title>
<authors>
<author>Alfred V. Aho</author>
<author>Ravi Sethi</author>
<author>Jeffrey D. Ullman</author>
</authors>
<publisher>Addison Wesley</publisher>
<published>1986-01-01</published>
<price>102.00</price>
<purchaseDate>2005-01-22</purchaseDate>
</book>
</availableBooks>
Here's another example with the <book>
and <borrower>
data combined in a single file:
(Note: The results are the same as above.)
combined.xml
<library>
<books>
<book asin="0201100886" created="128135928" lastLookupTime="128135928">
<uuid>BA57A934-6CDC-11D9-830B-000393D3DE16</uuid>
<title>Compilers</title>
<authors>
<author>Alfred V. Aho</author>
<author>Ravi Sethi</author>
<author>Jeffrey D. Ullman</author>
</authors>
<publisher>Addison Wesley</publisher>
<published>1986-01-01</published>
<price>102.00</price>
<purchaseDate>2005-01-22</purchaseDate>
</book>
<book asin="DEVNULL" created="128135928" lastLookupTime="128135928">
<uuid>98374982739847298347928374</uuid>
<title>Test Book</title>
<authors>
<author>DevNull</author>
</authors>
<publisher>Stackoverflow</publisher>
<published>2011-04-29</published>
<price>FREE</price>
<purchaseDate>2011-04-29</purchaseDate>
</book>
</books>
<borrowers>
<borrower id="1">
<name> John Doe </name>
<phone> 555-1212 </phone>
<borrowed>
<book asin="0138613370"/>
<book asin="0122513363"/>
<book asin="DEVNULL"/>
</borrowed>
</borrower>
</borrowers>
</library>
XQuery
<availableBooks>
{
for $library in doc("combined.xml")/library
for $book in $library/books/book
let $borrowed := $library/borrowers/borrower/borrowed/book
where not($borrowed[@asin = $book/@asin])
return $book
}
</availableBooks>
Upvotes: 3