Querying

Characteristics

Characteristics (2nd)

Where to use XQuery (and where not)

The XQuery domain is useful for:

In other cases:

Source code example

Example of source document, XML Queries on it and their results.

<?xml version="1.0" encoding="Windows-1250"?>
  <addressbook>
    <person category="friends">
      <firstname>Petr</firstname>
      <lastname>Novak</lastname>
      <date-of-birth>1969-05-14</date-of-birth>
      <email>novak@myfriends.com</email>
      <characteristics lang="en">Very good friend</characteristics>
    </person>
    <person category="friends">
      <firstname>Jaroslav</firstname>
      <lastname>Nováček</lastname>
      <date-of-birth>1968-06-14</date-of-birth>
      <email>novacek@myfriends.com</email>
      <characteristics lang="en">Another good friend</characteristics>
    </person>
    <person category="staff">
      <firstname>Jan</firstname>
      <lastname>Horak</lastname>
      <date-of-birth>1970-02-0</date-of-birth>
      <email>horak@mycompany.com</email>
      <characteristics lang="en">Just colleague</characteristics>
    </person>
    <person category="friends">
      <firstname>Erich</firstname>
      <lastname>Polak</lastname>
      <date-of-birth>1980-02-28</date-of-birth>
      <email>erich@myfriends.com</email>
      <characteristics lang="en">Good friend</characteristics>
    </person>
 </addressbook>

Example - Simple Query (XPath)

Running XQuery using Saxon 9.0j

XSLT processor Saxon contains the XQuery processor since version 8.x as well. To process XQuery you need:

Result

The query to above mentioned document will create the file result.xml:

<lastname>Novák</lastname> <lastname>Nováček</lastname>
<lastname>Horák</lastname> <lastname>Polák</lastname>

XQuery structure

FLWOR is an acronym of an XQuery structure. It roughly corresponds to the SQL query structure:

(F)or

Initial query part that specifies query cycle including control variable. Results of XPath expression behind the keyword " in" are assigned to the variable.

(L)et

You can assign values of next variable that can be used later in this section.

(W)here

specifies selection condition ie. which nodes (values) selected by for section will be used.The condition can utilize the variables defined in the "let" section.

(O)rder

Defines how the nodes should be ordered.

(R)eturn

Defines what is returned, constructed from extracted nodes (values).

FLWOR - simple example

Condition used to select requested nodes can be specified either in an XPath expression in "for" clause or in the "where" clause. "Return Mr. Polak’s birth-date."

for $person in
doc('myaddresses.xml')/addressbook/person where $person/lastname='Polák'
return $person/date-of-birth

XQuery returns:

<?xml version=" 1.0" encodings"UTF-8"?>
<date-of-birth>l980-02-28</date-of-birth>

FLWOR - Nested Queries

Sometimes is needed to iterate over the result of another query. You can do using the return statement - the return clause contains a nested query.

Nested Queries - Example Data

Example data

<warehouse>
  <categories>
    <category name="food">
      <item id="cheaproll"/>
      <item id="expensivebread"/>
    </category>
    <category name="hw">
      <item id="mb"/>
    </category>
  </categories>
  <items>
    <item id="cheapoll">
     <producer>1st bakeries</producer>
     <price unit="CZK">1</price>
    </item>
    <item id="expensivebread">
     <producer>2nd bakeries</producer>
     <price unit="USD">3</price>
    </item>
    <item id="mb">
      <producer>Homemade Electronics Inc.</producer>
      <price unit="EUR">100</price>
    </item>
  </items>
</warehouse>

Nested Queries - Example

The example gets detailed information on all products in category food:

 <foods>
 {
   for $foodId in //category[@name="food"]/item/@id
   return
      for $item in //items/item[@id=$foodId]
      return
    <food>
        {$item/@id}
        {$item/producer}
        {$item/price}
    </food>
 }
 </foods>

XQuery - Query Parameters

The XQuery parameters can be specified following way:

declare variable $id as xs:string external;

Example:

declare variable $cat as xs:string external;
<wares>
 {
   for $foodId in //category[@name=$cat]/item/@id
   return
      for $item in //items/item[@id=$foodId]
      return
      <ware>
        {$item/@id}
        {$item/producer}
        {$item/price}
     </ware>
}
</wares>

XQuery - Transformation attributes <→ elements

<some_new_element>
{
  data(xpath_to_attribute)
}
</some_new_element>
<food price="{XPath_to_the_element}"/>

XQuery and Namespaces

 <rich xmlns:pets="nsURI" xmlns:devs="nsURI">
  declare namespace pets="nsURI";
  declare namespace devs="nsURI";

XQuery Namespaces Demo

XQuery using namespaces

<rich xmlns:pets="http://www.fi.muni.cz/~bar/pets"
      xmlns:devs="http://www.fi.muni.cz/~bar/devices">
{
  for $rich_person in //person
  where sum($rich_person//pets:price)>100000 or
        sum($rich_person//devs:price)>150000
  return
  <rich-person name="{$rich_person/@name}">
        <pets-value>
         {
                sum($rich_person//pets:price)
         }
        </pets-value>
        <devs-value>
        {
                sum($rich_person//devs:price)
        }
        </devs-value>
  </rich-person>
}
</rich>

XQuery Implementation

SAXON since versions 7.x:

Native XML databases

Native XML database systems mostly support XQuery as a query language:

Recommended resources