XQuery Language. Introduction to databases CSCC43 Spring 2012 Ryan Johnson



Similar documents
Moving from CS 61A Scheme to CS 61B Java

Oracle Database: SQL and PL/SQL Fundamentals

Markup Languages and Semistructured Data - SS 02

Oracle Database: SQL and PL/SQL Fundamentals NEW

Structured vs. unstructured data. Motivation for self describing data. Enter semistructured data. Databases are highly structured

Data XML and XQuery A language that can combine and transform data

Oracle Database: SQL and PL/SQL Fundamentals

Microsoft' Excel & Access Integration

Duration Vendor Audience 5 Days Oracle End Users, Developers, Technical Consultants and Support Staff

MOC 20461C: Querying Microsoft SQL Server. Course Overview

Oracle SQL. Course Summary. Duration. Objectives

Data Structure with C

Cal Answers Analysis Training Part I. Creating Analyses in OBIEE

How To Use Query Console

Python Lists and Loops

Relational Databases

Instant SQL Programming

1 Introduction. 2 An Interpreter. 2.1 Handling Source Code

Creating a TEI-Based Website with the exist XML Database

Guide to Performance and Tuning: Query Performance and Sampled Selectivity

Object Oriented Software Design

Relational Database: Additional Operations on Relations; SQL

Exercise 4 Learning Python language fundamentals

COMP 5138 Relational Database Management Systems. Week 5 : Basic SQL. Today s Agenda. Overview. Basic SQL Queries. Joins Queries

Oracle Database 11g SQL

Oracle Database 12c: Introduction to SQL Ed 1.1

Object-Oriented Query Languages: Object Query Language (OQL)

A Comparison of Database Query Languages: SQL, SPARQL, CQL, DMX

Translating to Java. Translation. Input. Many Level Translations. read, get, input, ask, request. Requirements Design Algorithm Java Machine Language

Object Oriented Software Design

Introduction to Python

SQL Server for developers. murach's TRAINING & REFERENCE. Bryan Syverson. Mike Murach & Associates, Inc. Joel Murach

Discovering SQL. Wiley Publishing, Inc. A HANDS-ON GUIDE FOR BEGINNERS. Alex Kriegel WILEY

Informatica e Sistemi in Tempo Reale

Database Programming with PL/SQL: Learning Objectives

Advanced Query for Query Developers

A binary search tree or BST is a binary tree that is either empty or in which the data element of each node has a key, and:

Computer Programming I

Querying Microsoft SQL Server

JavaScript: Introduction to Scripting Pearson Education, Inc. All rights reserved.

Oracle Database: SQL and PL/SQL Fundamentals NEW

The C Programming Language course syllabus associate level

WebSphere Business Monitor

CS106A, Stanford Handout #38. Strings and Chars

Writing Control Structures

Performing Queries Using PROC SQL (1)

Data Tool Platform SQL Development Tools

Introducing Microsoft SQL Server 2012 Getting Started with SQL Server Management Studio

2874CD1EssentialSQL.qxd 6/25/01 3:06 PM Page 1 Essential SQL Copyright 2001 SYBEX, Inc., Alameda, CA

Command Scripts Running scripts: include and commands

Oracle Database 10g: Introduction to SQL

Course ID#: W 35 Hrs. Course Content

Querying Microsoft SQL Server 20461C; 5 days

Chapter 5 More SQL: Complex Queries, Triggers, Views, and Schema Modification

VISUAL GUIDE to. RX Scripting. for Roulette Xtreme - System Designer 2.0

Introduction to Pig. Content developed and presented by: 2009 Cloudera, Inc.

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

Python Loops and String Manipulation

Damia: Data Mashups for Intranet Applications

AN INTRODUCTION TO THE SQL PROCEDURE Chris Yindra, C. Y. Associates

Inside the PostgreSQL Query Optimizer

Concepts and terminology in the Simula Programming Language

Information Systems SQL. Nikolaj Popov

Data Integration through XML/XSLT. Presenter: Xin Gu

Regression Verification: Status Report

Computers. An Introduction to Programming with Python. Programming Languages. Programs and Programming. CCHSG Visit June Dr.-Ing.


White Paper. Blindfolded SQL Injection

CS 141: Introduction to (Java) Programming: Exam 1 Jenny Orr Willamette University Fall 2013

Querying Microsoft SQL Server Course M Day(s) 30:00 Hours

Crystal Reports Form Letters Replace database exports and Word mail merges with Crystal's powerful form letter capabilities.

Querying Microsoft SQL Server 2012

Glossary of Object Oriented Terms

Comp 5311 Database Management Systems. 3. Structured Query Language 1

Deferred node-copying scheme for XQuery processors

Paper An Introduction to SAS PROC SQL Timothy J Harrington, Venturi Partners Consulting, Waukegan, Illinois

SQL: Queries, Programming, Triggers

Master of Sciences in Informatics Engineering Programming Paradigms 2005/2006. Final Examination. January 24 th, 2006

Chapter 15 Functional Programming Languages

Chapter 13: Query Optimization

Example Instances. SQL: Queries, Programming, Triggers. Conceptual Evaluation Strategy. Basic SQL Query. A Note on Range Variables

Course 10774A: Querying Microsoft SQL Server 2012

Course 10774A: Querying Microsoft SQL Server 2012 Length: 5 Days Published: May 25, 2012 Language(s): English Audience(s): IT Professionals

Oracle Database: Introduction to SQL

MongoDB Aggregation and Data Processing Release 3.0.4

COMP 110 Prasun Dewan 1

Binary Heap Algorithms

16.1 MAPREDUCE. For personal use only, not for distribution. 333

MOC QUERYING MICROSOFT SQL SERVER

Syntax Check of Embedded SQL in C++ with Proto

C Compiler Targeting the Java Virtual Machine

Oracle Database: Introduction to SQL

Chapter 5. SQL: Queries, Constraints, Triggers

Structured vs. unstructured data. Semistructured data, XML, DTDs. Motivation for self-describing data

G563 Quantitative Paleontology. SQL databases. An introduction. Department of Geological Sciences Indiana University. (c) 2012, P.

Database Applications Microsoft Access

Static vs. Dynamic. Lecture 10: Static Semantics Overview 1. Typical Semantic Errors: Java, C++ Typical Tasks of the Semantic Analyzer

Transcription:

XQuery Language Introduction to databases CSCC43 Spring 2012 Ryan Johnson Thanks to Manos Papagelis, John Mylopoulos, Arnold Rosenbloom and Renee Miller for material in these slides

Quick review of XPath 2 Strengths Compact syntax Efficient XML tree traversal Predicates filter out nodes we don t want Weaknesses Declarative (no control flow) Most joins impossible (self-joins possible but ugly) Little/no ability to manipulate XML Can t format results No way to specify input! We just spent the last couple of days becoming familiar with XPath, and its weaknesses... overall, it s great for what it does, but very limited. It s certainly far less capable than SQL, let alone a full programming language. The lack of loops, variables, and any form of aggregation is limiting, but one of the biggest problems is that the way xpath produces output.

Why might we manipulate XML? Consider the XPath query book-list[book/author/last-name = Asimov ] => returns a list of complete book elements How to turn that into the following? <book-list> <book> <title>i, Robot</title> <publisher>gnome Press</publisher> </book>... </book-list> XPath union operator isn t enough Flat list of title and publisher elements => What if <!ELEMENT book (title*, publisher*,...)>? 3 XPath can only return full (not sparse ) subtrees The output of an xpath operation is a list of nodes, strings, and/or attributes (depending on the query), none of which are valid XML documents. As a simple example, suppose we wanted the title and publisher of all books by Isaac Asimov. We might issue something like the following (assuming xpath-2.0 syntax): /book-list/book[author/last-name= Asimov ]/(title publisher) It would return a list like the following: <title>i, Robot</title><publisher>Gnome Press</publisher><title>Foundation</title><publisher>Gnome Press</publisher><title>Nemesis</title><publisher>Doubleday</publisher><title>Nightfall</title><publi sher>doubleday</publisher> In theory we could reconstruct the original title-publisher pairs, but it s extra work and would fail if title or publisher were optional. The only alternative is to return entire book elements that meet the match condition, but that brings along unwanted extra information. What we really want is a way to control the structure of output; given a set of matching elements we should be able to produce a new XML document that incorporates them. This is precisely what xquery was designed for.

How XQuery can be used? 4 Extracting information from a database for use in a web service or an application integration Generating reports on data stored in an XML database Transforming XML data to XHTML to be published on the Web Searching textual documents on the Web Splitting up a large XML document to multiple XML documents XQuery 5 Address most weaknesses with XPath without adding too much complexity Primary features access methods (read XML from file, etc.) control flow: if/then/else, iteration variables functions (both user-defined and library flavors) XML transformation: make data presentable sorting, more powerful predicates, set operations... Expressiveness: XPath << SQL << XQuery

Key concepts of XQuery 6 Template of sorts: mixed output and logic Statically define the overall structure Embed logic to inject input data in right places All expressions return XML Like in RA, outputs of one operation can be input to another Returned value may be text, element, or node set FLWOR expressions Allow iteration over node sets and other sequences Functions Allow logic encapsulation, recursion NOTE: XQuery syntax bleeds back into XPath XQuery is a form of static template language: code and output formatting can interleave freely, with code that returns snippets of templated XML embedded in a larger XML template. Unlike xpath, xquery always returns something that can become input for further processing, and user-defined functions (including recursion) allow flexible designs.

Basic XQuery code format <title>useful information about Tor:</title> <books-by-tor> { //book[publisher= Tor ]/title } </books-by-tor> <authors-with-tor> {//book[publisher= Tor ]/author/last-name} </authors-with-tor> static template interpreted code 7 Oops! Author list has duplicates... This is an example of a static template with some bits of live code embedded in strategic locations. Some header information is produced first, followed by a list of book titles; the xpath expression is not formatted further, so the returned nodes are simply inserted where the code that produced them used to be. A second section repeats the process, this time filling out an author list with author last names fetched by a second xpath expression. A couple of things worth noting: The author list probably has duplicates (authors who published multiple books), ideally we d have a way to get rid of those (stay tuned!) There is non-trivial redundancy here, left over from our xpath days: //book[publisher= Tor ] is used twice. It would be better to store the book list in a variable and process it twice, rather than running the xpath twice.

FLWOR ( flower ) expressions XPath: //book[publisher= Tor and author/last-name= Asimov ]/*[self::author self:: title] FLWOR: for $b in //book let $a := $b/author where $b/publisher = Tor and $a/last-name= Asimov order by $b/title return <book>{$b/title,$a}</book> 8 In what ways is the FLWOR superior to the XPath? The core of the xquery language is called a FLWOR expression (sometimes given as FLOWR ). FLWOR brings five key features to the language: Iteration over nodesets. Iterate over all elements in a variable or matched by an xpath expression Variable declarations. Store intermediate results for later re-use, avoiding redundancy and improving performance Selection. Allows more flexible types of predicates than those supported in xquery, particularly when comparing elements from nested loops Ordering. Sorting capabilities like those we ve come to expect from SQL Output formatting. No need to return the raw output of an xpath; each item in an iteration can be formatted in near-arbitrary ways before returning it to its caller. One really important thing about return in xquery: it is *not* like the return statement of a language like python or Java. In those languages, return ends the computation and returns a single value. In xquery, a return statement just adds a value to a list. That list (which may be empty) will be returned to the caller once the computation completes. The closest thing in python would be the yield statement, which returns a single value to the caller without ending the computation; Java has no such concept.

Characteristics of a FLWOR F(or) Iterate over each item in a sequence Multiple sequences separated by commas L(et) Declares a variable and assigns it a value Multiple declarations separated by commas Assigned at start of each iteration of the for above it W(here), O(rder by) Stolen shamelessly from SQL... R(eturn) The value produced by the current iteration FLWOR is an expression, NOT a function call! => Result is a sequence of returned values 9 Have as many F and L as you want, in any order FLWOR expressions can be nested in two ways. The simple form of nesting lets you use F and L as many times as you want, in any order, but you only get to use W, O and R once. The other way to nest FLWOR is to realize that they are expressions and can therefore be used anywhere an expression is allowed. In particular, you could have one FLWOR iterate over the result produced by another FLWOR. We ll see examples of this a bit later.

Output behaviour of FLWOR 10 In XPath, every node output at most once Predicates just mark nodes which pass All marked nodes output at end Cartesian product impossible ==> most joins impossible In FLWOR, node output with every return Every node in a node set bound to the loop variable Emit any that make it past the where clause Distinction matters for nested loops! Cartesian product: for $x in //book, $y in //book... We already talked a little bit about return in xquery, and how it s different than return in Python or Java. We should also point out that FLWOR returns things differently than xpath. In xpath, every predicate can mark zero or more elements as valid, and the returned result is just the union of elements marked this way. There is no way to return an element twice, and there is no way to unmark an element after a predicate marks it as valid. There is no way to compute an intersection (nodes can t be unmarked), and there is no way to produce a Cartesian product, which rules out joins as well. xquery has neither problem. Every FLWOR can apply new filtering steps to refine the results of previous ones, and nothing stops the programmer from storing a result set in a variable and iterating over it as many times as they want, including with nested loops.

Sequences in XQuery 11 Most expressions return sequences of nodes LET $b = /bib/book ==> $b is a sequence $b/@isbn ==> a sequence $b/price ==> sequence of n prices $b/price * 0.7 ==> sequence of n numbers Sequence literals also allowed e.g. (1,2,3), also shortcut for ranges: (1 to 10) empty sequence: () Sequences combine easily, flatten automatically (1, 2, (3, 4, 5), (), 6, 7) ==> (1, 2, 3, 4, 5, 6, 7) The basic unit of work in xpath is a sequence: an ordered list of elements, possibly with duplicates. Xpath queries return sequences, as do FLOWR expressions, and sequence literals can be specified with a tuple syntax similar to the one used in python. Unlike python, however, sequences in xquery are always flat: putting two or more sequences together returns a new sequence that contains the elements of its inputs. This is true even if you try to make a sequence as an element inside another sequence (which can happen if a FLWOR returns sequences rather than elements). Sequences may contain elements, attributes, or atomic values like strings and numbers. Sequences can even be mixed, containing elements of different types, though this is usually not a good idea (it s much more useful to group mixed sequences into new xml nodes that can be easily processed later with additional xpath queries).

RETURN gotchas 12 Must use a sequence to return multiple values Broken: for... return $x,$y => parses as (for... return $x),$y Correct: for... return ($x,$y) Need { } when inside templates: Broken: return <i>$title</i> Correct: return <i>{$title}</i> Only need { } when inside templates Broken: return (<i>{$title}</i>,{$rest}) Correct: return (<i>{$title}</i>,$rest) What the slide says. These are easy to trip over, but just as easy to fix once you know what the problem is.

If-then-else expressions 13 Syntax is very C-like: if ($expr) then $expr else $expr BUT, like FLWOR, it is an expression! for $b in //book return if ($b/publisher = Tor ) then <book>{$b/(title author)}</book> else () xquery includes an if/then conditional syntax, like most languages. However, it s not a statement but rather an expression. Instead of saying if $condition is true, *do* x else *do* y if/then in xquery says if $condtion is true, *return* x else *return* y (where return has its usual xquery meaning). This is a lot like the :? syntax in C or Java.

Advanced predicates on node sets 14 So far, two ways of predicating on node sets Test for empty/non-empty Iterate over their members and apply a predicate Two other techniques exist also Explicit quantification Single-object matching

Quantification XPath implicitly uses existential quantification //genre[.//author/last-name= Asimov ]/@name => Names every genre containing at least one book by Asimov => Tests whether.//author/last-name[. = Asimov ] is empty XQuery adds explicit control Existential ( ): some $x in $y satisfies $expr Universal ( ): every $x in $y satisfies $expr Examples //genre[some $n in.//author/last-name satisfies $n= Asimov ]/@name /transcript/semester[every $m in mark satisfies $m > 3.5] /transcript/semester[some $m in mark satisfies $m < 2.0] 15 Quantification, what joy. Remember from xpath, how any predicates comparing scalars to sequences return a new sequence containing only those elements that match the scalar comparison? This is existential quantification any element matching is enough to make the expression true. XQuery defaults to existential quantification as well, but also allows the user to explicitly request either existential or universal quantification. Universal quantification means that every element must match or else the expression is false. Note that, either way, xquery follows Xpath in treating empty as false and non-empty as true.

Comparisons General comparisons Apply to sequences of objects (same as XPath) Operators: =!= < > <= >= A op B is true <==> x A and y B s.t. x op y is true Value comparison operators Compare the values of two objects Operators: eq, ne, lt, gt, le, ge Error if both sides cannot be atomized to primitive types Node comparisons Compare identity of two nodes based on position in document Operators: is, << (for preceding), >> (for following) is only true if both sides are actually the same node 16 Most comparisons are like the ones in any other language, but there are some special cases to be aware of. First, xquery introduces a second set of comparators that only operate on objects, and return an error if they encounter a sequence as either operand. Second, xquery gives a way to work with identities of elements, rather than their values. Identity is based on a node s position in the original document. We can test whether two variables contain exactly the same element (the self axis in xpath), and also test whether an element comes before/after some other element (the preceding and following axes in xpath).

= vs. eq 17 for $b1 in //book, $b2 in //book where $b1/* = $b2/* return <hit>{$b1,$b2}</hit> => Return every pair of books with any of: same author, same genre, same publisher, same price... => Using eq gives error if count($b/*)!= 1 //book[price gt 10] => Type error: price (untyped)!= 10 (integer) => Use //book[xs:integer(price) gt 10] => = converts simple types automatically A couple of examples to think about...

Set operations 18 XPath defines only union ( ) XQuery adds union, intersect, except operators stolen shamelessly from SQL Also, duplicate elimination: distinct-values() Compares nodes but returns values Attributes and children (recursively) must also match => match usually means same node in the source doc Returned output is sequence of strings Unfortunately, the function distinct-values does exactly what its name suggests: it converts each sequence element into text and then deduplicates the resulting sequence of strings. This is not very useful in practice: think of all those <book> elements containing seemingly-identical <author><firstname>isaac</first-name><last-name>asimov</last-name></author> elements; if we select them with an xpath query and try to use them as input to a later operation, we either have to be content with working on strings from then on or live with the duplicates. Later on, we ll define a function that returns distinct members of any sequence (nodes, attributes, or atomic values) instead.

User-defined functions 19 Example declare function local:count-nodes($e as element()) as integer { 1 + sum( for $c in $e/* }; return count-nodes($c) ) return type semicolon not optional! Arguments can be typed Parenthesis after type names Cardinality controlled in the usual way: +? * Default type: item()* Function body is an expression to evaluate Ironically, functions don t use the return keyword! Recursion allowed Now we re getting to the good stuff: we can define our own functions to encapsulate common operations and allow recursion. The implications are exciting, but the syntax itself is not complex, so there s little more to say about it here. The function here defines a recursive node-counter: the count of a node is 1 + the counts of its children (leaf nodes therefore have count 1). One annoying detail: unless you tell it otherwise, the xquery engine assumes your new function belongs in the fn: namespace (since that s where all functions live by default). However, the fn namespace is restricted, meaning that only built-in functions are normally allowed there. You can either declare your own namespace and put the function inside it, or just put it in namespace local

Duplicate elimination XQuery often produces duplicates //book[publisher= Tor ]/author/last-name Solution: distinct-values()? Atomizes inputs (elements become strings) Good for ints, strings; useless for elements distinct-values((1, 2, 3, 1, 2)) = (1, 2, 3) Solution: XPath s index-of() function index-of((x 1,x 2, ), $y) returns position() of $x i where $x i =$y index-of((a,b,c,b,a), a) = (1,5) index-of ((15, 40, 25, 40, 10), 18) = () index-of (("a", "dog", "and", "a", "duck"), "a") = (1, 4) 20 As promised, now that we have user-defined functions, our first order of business is to define a general deduplication routine. The key is a built-in xquery function called index-of, which takes a sequence and an item, and returns all positions in the sequence that compare equal to the item. There could be zero, one, or many such matches.

Deduplication using index-of() 21 Consider index-of($x, $y)[1] Return the first (in document order) $z in $x satisfying $y=$z Solution: $x[position()=index-of($x,.)[1]] Return every $z in $x which is the first in its set of matches Abbreviated syntax: $x[index-of($x,.)[1]] WARNING: only reliable for document root! /a/b[index-of(/a/b,.)[1]] fails in strange ways => ALWAYS assign non-root sequences to a variable first Armed with index-of, all we need to do is arrange to call index-of on every element of a sequence, matching against that same sequence. Then, we only return the element if it is the first (or last) of its kind. Since only one element can be the first of its kind in a given sequence, the result is a sequence containing no duplicates. PLEASE pay attention to that warning!!! Always always always assign a sequence to a variable before deduplicating it. If you don t, this trick can fail in strange ways as queries become more complex, and it s always a real pain to debug.

Node deduplication examples Author list example <authors>{//book[publisher= Tor ]/author}</authors> One-off deduplication <authors> {let $a := //book[publisher= Tor ]/author return $a[index-of($a,.)[1]]}</authors> Even better: encapsulate it in a function! declare function local:distinct($a) { $a[index-of($a,.)[1]] }; <authors>{ local:distinct(//book[publisher= Tor ]/author) }</authors> Can also define duplicate more narrowly let $b := /book-list/book[publisher= Tor ] return $b[index-of($b/author/last-name,./author/last-name)[1]] Returns one (arbitrary) book for each author last name 22 23 XQUERY EXAMPLES THANKS TO VASSILIS CHRISTOPHIDES FOR MATERIAL IN THESE SLIDES

Example: XML Doc 24 <bib> <book year="1994"> <title>tcp/ip Illustrated</title> <author> <last>stevens</last> <first>w.</first></author> <publisher>addison-wesley</publisher> <price>65.95</price> </book> <book year="1992"> <title>advanced Programming the Unix environment</title> <author> <last>stevens</last> <first>w.</first></author> <publisher>addison-wesley</publisher> <price>65.95</price> </book> Example: XML Doc (cont.) 25 <book year="2000"> <title>data on the Web</title> <author><last>abiteboul</last> <first>serge</first></author> <author><last>buneman</last> <first>peter</first></author> <author><last>suciu</last> <first>dan</first></author> <publisher>morgan Kaufmann Publishers</publisher> <price>39.95</price> </book> <book year="1999"> <title>the Economics of Technology and Content for DigitalTV </title> <editor><last>gerbarg</last><first>darcy</first><affiliation>citi</affiliation> </editor> <publisher>kluwer Academic Publishers</publisher> <price>129.95</price> </book> </bib>

FLWOR Expression Example 26 Query1: Find all books titles published after 1995 FOR $x IN doc("bib.xml")/bib/book WHERE $x/year > 1995 RETURN $x/title For brevity, later slides assume bib.xml is root Result: <title>tcp/ip Illustrated</title> <title>advanced Programming the Unix environ </title> <title>data on the Web</title> <title>the Economics of Technology and </title> More complex FLWOR 27 Query2: List all books of authors published by Morgan Kaufmann LET $b:=/bib/book FOR $a IN local:distinct( $b[publisher= Morgan Kaufmann ]/author) RETURN <result> {$a} {FOR $t IN $b[author=$a]/title RETURN $t} </result>

More complex FLWOR (cont.) 28 Query3: Find books whose price is larger than average LET $a := avg(/bib/book/price) FOR $b in doc(/bib/book WHERE $b/price > $a RETURN $b avg: aggregate function that returns the average GROUP BY and HAVING in XQuery 29 Query4: Group by author name their first ten books, for authors having written more than ten books FOR $a IN local:distinct(//book/author/lastname) LET $books := //book[some $y IN author/lastname = $a] WHERE COUNT( $books )>10 RETURN <result> {$a} { $books[1 to 10] } </result>

Joins in XQuery 30 Query5: For each book title list the prices offered by Amazon and Barnes&Noble <books-with-prices> {FOR $a IN doc( amazon.xml )/book, $b IN doc( bn.xml )/book WHERE $b/@isbn = $a/@isbn RETURN <book> { $a/title } <price-amazon>{ $a/price }</price-amazon>, <price-bn>{ $b/price }</price-bn> </book> } </books-with prices> Outer Joins in XQuery 31 Query5: For each book Amazon sells, give the price B&N charges <books-with-prices> {FOR $a IN doc( amazon.xml )/book RETURN <book> { $a/title } <price-amazon>{ $a/price }</price-amazon>, {FOR $b IN doc( bn.xml )/book WHERE $b/@isbn = $a/@isbn RETURN <price-bn>{ $b/price }</price-bn> } </book> } </books-with prices>

Full-outer Joins in XQuery 32 Query5: For each book either Amazon or B&N sells, list both prices LET $allisbns:= distinct-values(doc( amazon.xml )/book/@isbn union doc( bn.xml )/book/@isbn) RETURN <books-with-prices> {FOR $isbn IN $allisbns RETURN <book> {FOR $a IN doc( amazon.xml )/book[@isbn=$isbn] RETURN <price-amazon>{ $a/price }</price-amazon>} {FOR $b IN doc( bn.xml )/book[@isbn=$isbn] RETURN <price-bn>{ $b/price }</price-bn>} </book>} </books-with-prices> If-Then-Else in XQuery 33 Query6: Make a list of holdings, ordered by title. For journals, include the editor, and for all other holdings, include the author FOR $h IN //holding ORDER BY title RETURN <holding> {$h/title} {IF ($h/@type = Journal ) THEN $h/editor ELSE $h/author} </holding>

Existential Quantifiers in XQuery 34 Query7: Find titles of books in which both sailing and windsurfing are mentioned in the same paragraph FOR $b IN //book WHERE SOME $p IN $b//paragraphs SATISFIES contains($p, "sailing") AND contains($p, "windsurfing") RETURN $b/title Universal Quantifiers in XQuery 35 Query8: Find titles of books in which sailing is mentioned in every paragraph FOR $b IN //book WHERE EVERY $p IN $b//paragraphs SATISFIES contains($p, "sailing") RETURN $b/title

Sorting in XQUERY 36 Query9: Find the publishers and the books they have published, order by publisher name and then by book price descending <publisher-list> FOR $p IN distinct-values(//publisher) ORDER BY name RETURN <publisher> <name> $p/text() </name>, FOR $b IN //book[publisher = $p] ORDER BY price DESCENDING RETURN <book> $b/title, $b/price </book> </publisher> </publisher-list> User-specified Functions in XQuery 37 Query10: Find the maximum depth of the document named "partlist.xml" NAMESPACE xsd="http://www.w3.org/2001/xmlschemadatatypes" DECLARE FUNCTION local:depth(element $e) AS xsd:integer { (: An empty element has depth 1 : Otherwise, add 1 to max depth of children :) IF empty($e/*) THEN 1 ELSE max(depth($e/*)) + 1 } depth(doc("partlist.xml"))