XQuery function - count

Im looking for an xQuery form that returns a book category if that category contains more than x number of books. For example, if I have 4 categories; music, film, education, health, and they all have 1 book, except for music, which has 3, they need to list this category. Ive tried a number of queries, but everything seems to be correct, I just don’t get the result every time, I think that at some point I need to use a certain value? Not too sure.

The following is an example of a source that tests the query in an editor that does not save the source file as a file, so to check xQuery you need to start with:

eg. for $ x in / bookstore / book ...

<bookstore> <book category="Music"> <year>  2005  </year> <price>  50  </price> </book> <book category="Music"> <year>  2010  </year> <price>  35  </price> </book> <book category="Music"> <year>  1982  </year> <price>  70  </price> </book> <book category="Film"> <year>  2000  </year> <price>  10  </price> </book> <book category="Health"> <year>  1965  </year> <price>  50  </price> </book> <book category="Education"> <year>  2012  </year> <price>  70  </price> </book> </bookstore> 

Any help is greatly appreciated!

+7
source share
3 answers

Like @koopajah's answer, and since I already wrote this, I will post it ...

 for $category in distinct-values(/*/book/@category) where count(/*/book[@category=$category]) >= 3 return <results>{$category}</results> 

With an external document ...

 let $doc := doc('input.xml') for $category in distinct-values($doc/*/book/@category) where count($doc/*/book[@category=$category]) >= 3 return <results>{$category}</results> 

Changed xquery from comment ...

 for $x in doc('input.xml')/bookstore for $y in distinct-values($x/book/@category) where count($x/book[@category=$y]) >= 3 return $y 
+5
source

Use this XQuery, which is also a pure XPath 2.0 expression. Note distinct-values() not used :

 (/*/*/@category)[index-of(/*/*/@category, .)[3]]/string() 

When evaluating the provided XML document :

 <bookstore> <book category="Music"> <year> 2005 </year> <price> 50 </price> </book> <book category="Music"> <year> 2010 </year> <price> 35 </price> </book> <book category="Music"> <year> 1982 </year> <price> 70 </price> </book> <book category="Film"> <year> 2000 </year> <price> 10 </price> </book> <book category="Health"> <year> 1965 </year> <price> 50 </price> </book> <book category="Education"> <year> 2012 </year> <price> 70 </price> </book> </bookstore> 

required, the correct result is obtained :

 Music 
+4
source

I just tried this query in a BaseX database and it seems to work the way you expect:

 for $cat in distinct-values(/bookstore/book/@category) let $nbBook := count(/bookstore/book[@category=$cat]) return if($nbBook > 1) then $cat else '' 
+2
source