FLWOR Expression used for a join, What am I missing?


I must be missing something real obvious here. I have two xml files (books1.xml and books2.xml) that represent book collections. The files have a format like this:

TCP/IP Illustrated StevensW. Addison-Wesley 65.95 Advanced Programming in the UNIX Environment StevensW. Addison-Wesley 65.95

There are some books listed in books1.xml that are not in books2.xml. I attempted to write a query that returned just the books missing from books2.xml, assuming that the attribute year was unique. The query looked like this:

for $a in doc(“container1\books1.xml”)\book
let $b := doc(“container1\books2.xml”)\book
where $a@year != $b@year
return $a

This query returns all of the books in $a. If I change the where clause to ‘where $a@year = $b@year’, then the query returns all the files in $a that are also in $b. What am I missing?




The “let” clause in your query binds all books in “container1/books2.xml” to the variable $b.
Due to this the predicate in the “where” clause performs a general comparison between the publication years of all book in “container1/books2.xml” and the publication year of the “book” element bound to variable $a. The general comparison will result into “true” as soon as there is a “book” element with a publication year that is not equal to $a/@year. Assuming that there is such a “book” element you will get all books in “container1/books1.xml”. In order to get just those books not contained in “container1/books2.xml” you have to apply the not() function in the following way:

for $a in doc(“container1/books1.xml”)//book
let $b := doc(“container1/books2.xml”)//book
where not($a/@year = $b/@year)
return $a

Best Regards,

Thorsten Fiebig