zach
zach

Reputation: 55

xquery for loop questions

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

Answers (2)

Michael Kay
Michael Kay

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

Daniel Haley
Daniel Haley

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

Related Questions