The Structure of XQuery
Having described why XQuery is more or less necessary, let's look at its general makeup. The language consists of these primary areas:
for/letAnalogous to the SQL SELECT and SET statements, the for and let clauses let you define variables or iterate across a range of sequence values that are in turn assigned to a variable.
whereAnalogous to the SQL WHERE statement, the where clause provides a set of conditions that filter or limit the initial selection in a for statement.
order-byAnalogous to SORT BY in SQL, order-by provides the ordering constraints on a sequence.
returnAnalogous to the SQL RETURN statement, the XQuery return clause uses a custom formatting language to create output. The output does not necessarily have to be XML, although it is optimized to produce XML.
XPathMost XPath 2.0 functions are supported in XQuery, as is the axis model used to navigate over XML structures (although some data sources might not support all aspects of XPath because of the type of data involved).
FunctionsAnalogous to SQL stored procedures, you can define functions in XQuery using the XPath language that can be called inline in an XML query.
NamespacesA feature of XML rather than SQL. The declare namespace function associates a namespace URI with a prefix, crucial for indicating functionality.
Any number of keywords are associated with XQuery, but these broad categories describe different syntaxes depending upon what specifically needs to be done. For instance, here's an example of a full XQuery expression that uses all five of these areas:
declare namespace xs = "http://www.w3.org/2001/XMLSchema" define function summaryText($char) returns xs:string { concat($char/name,' is a ',$char/gender,' ',$char/species) } <results>{ let $chars := input()//character[gender = 'Female'] for $char in $chars where $char/level gt 5 return <summary health="{$char/health}"> { attribute level {$char/level}, attribute date {current-dateTime()}, summaryText($char) } </summary> } </results>
This is a query for pulling out a series of records from a game database. It assumes an initial XML data stream with records corresponding to different characters, as shown in the file characters.xml:
<characters> <character> <name>Aleria</name> <gender>Female</gender> <species>Heroleim</species> <vocation>Bard</vocation> <level>5</level> <health>25</health> </character> <character> <name>Shar</name> <gender>Male</gender> <species>Human</species> <vocation>Merchant</vocation> <level>6</level> <health>28</health> </character> <character> <name>Gite</name> <gender>Female</gender> <species>Aelvar</species> <vocation>Mage</vocation> <level>7</level> <health>18</health> </character> <character> <name>Horukkan</name> <gender>Male</gender> <species>Udrecht</species> <vocation>Warrior</vocation> <level>5</level> <health>32</health> </character> <character> <name>Gounna</name> <gender>Female</gender> <species>Noleim</species> <vocation>Mage</vocation> <level>8</level> <health>31</health> </character> <character> <name>Sheira</name> <gender>Female</gender> <species>Human</species> <vocation>Cleric</vocation> <level>4</level> <health>9</health> </character> <character> <name>Drue</name> <gender>Female</gender> <species>Voleim</species> <vocation>Warrior</vocation> <level>6</level> <health>32</health> </character> <character> <name>Paccu</name> <gender>Male</gender> <species>Human</species> <vocation>Merchant</vocation> <level>5</level> <health>24</health> </character> </characters>
When the query is executed, it returns an XML document showing all female characters that are of greater than fifth level, with a text summary:
<results> <summary date="2002-10-24T14:38:48" health="18" level="7"> Gite is a Female Aelvar</summary> <summary date="2002-10-24T14:38:48" health="31" level="8"> Gounna is a Female Noleim</summary> <summary date="2002-10-24T14:38:48" health="32" level="6"> Drue is a Female Voleim</summary> </results>
Note that this output has been reformatted somewhat to make it more legible. Whitespace is not usually significant in XQuerywithout the formatting, the result of the previous query is as follows:
<results><summary date="2002-10-24T14:38:48" health="18" level="7"> Gite is a Female Aelvar </summary><summary date="2002-10-24T14:38:48" health="31" level="8">Gounna is a Female Noleim </summary><summary date="2002-10-24T14:38:48" health="32" level="6">Drue is a Female Voleim </summary> </results>
Because each of the major areas has its own language and syntax, the best way to understand the full XQuery language is to break it into the code for each type of expression.