When a query becomes large and complex, it is often much easier to understand if it is divided into functions, and these functions can be reused in other parts of the query. For instance, we have seen a query that inverts a hierarchy to create a list of books by each author in a bibliography. It contained the following code: for $b in doc("books.xml")/bib/book where some $ba in $b/author satisfies ($ba/last=$l and $ba/first=$f) order by $b/title return $b/title This code returns the titles of books written by a given author whose first name is bound to $f and whose last name is bound to $l . But you have to read all of the code in the query to understand that. Placing it in a named function makes its purpose clearer: define function books-by-author($last, $first) as element()* { for $b in doc("books.xml")/bib/book where some $ba in $b/author satisfies ($ba/last=$last and $ba/first=$first) order by $b/title return $b/title } XQuery allows functions to be recursive, which is often important for processing the recursive structure of XML. One common reason for using recursive functions is that XML allows recursive structures. For instance, suppose a book chapter may consist of sections, which may be nested. The query in Listing 1.19 creates a table of contents, containing only the sections and the titles, and reflecting the structure of the original document in the table of contents. Listing 1.19 Query to Create a Table of Contentsdefine function toc($book-or-section as element()) as element()* { for $section in $book-or-section/section return <section> { $section/@* , $section/title , toc($section) } </section> } <toc> { for $s in doc("xquery-book.xml")/book return toc($s) } </toc> If two functions call each other, they are mutually recursive. Mutually recursive functions are allowed in XQuery. |