2

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>
5
  • You should post an example of what you are trying to do. It sounds like a simple XPath will return what you need, but it's hard to tell without an example. Commented Apr 30, 2011 at 5:05
  • <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> Commented Apr 30, 2011 at 5:11
  • <borrowers> <borrower id="1"> <name> John Doe </name> <phone> 555-1212 </phone> <borrowed> <book asin="0138613370"/> <book asin="0122513363"/> </borrowed> </borrower> Commented Apr 30, 2011 at 5:12
  • so if the asin in the book tag matches the asin in the book tag of the borrowers then i dont want to return it because it is checked out. Commented Apr 30, 2011 at 5:12
  • 1
    Are both of these XML structures (<book> and <borrowers>) contained in the same file? Commented Apr 30, 2011 at 5:26

2 Answers 2

3

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>
Sign up to request clarification or add additional context in comments.

Comments

2

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)]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.