Introduction to XML in DB2 11 for z/OS – Part 6 – XQuery basics

Today’s post builds on the previous one, where the XPath was briefly introduced. It will introduce the XQuery language and cover a basic subset of this language, including constructor and FLWOR expressions. Both expressions will be useful in SQL/XML functions in DB2 for z/OS which will be discussed in the next article.

XQuery

XML Query (XQuery) is a query language for retrieving and transforming data stored in the form of XML. It is a W3C Recommendation. XQuery is a superset of XPath, has flexible syntax, and is built around XPath expressions.    

All XQuery expressions operate on sequences, and evaluate to sequences. A sequence is an ordered list of items. An item can be either a node or an atomic value. A node represents a component of an XML document. (For more information about XML document structure, see a previous post.) An atomic value is an instance of an XML Schema-based type such as xs:integer or xs:string. Note that a sequence can also be empty or consist of only a single item, but cannot be nested. XQuery uses a comma operator to concatenate items into sequences.

For example, the expression below evaluates to a sequence of three items: an integer, a string and a decimal number. You can use brackets to group expressions.

((), 22, ("Chicken", 18.05)) evaluates to 22, "Chicken", 18.05

In later examples, the following XML document will be used:

<?xml version= "1.0" ?>
<blog id="3011975">
 <title>Cook Diary</title>
 <author>Iloita</author>
 <url>cookdiary.com</url>
 <articles>
   <article aid="00001" promoted="YES">
     <title>
       Best Chicken Tikka Masala
      </title>
     <tag>
       chicken
      </tag>
   </article>
   <article aid="00002" promoted="NO">
     <title>
       How to Make Besan Ladoo
      </title>
     <tag>
       sweets
      </tag>
   </article>
   <article aid="00003" promoted="NO">
     <title>
       Chocolate Ganache  
     </title>
     <tag>
       sweets
     </tag>
   </article>
 </articles>
</blog>

XQuery_Example1.jpg

Color legend:

  • Gray – document node
  • Dark blue – element
  • Orange – attribute
  • Light blue – element value

XQuery types, operators and functions

XQuery is a strongly typed language that can process strongly or weakly typed XML data. XQuery and XPath share a common data model and a set of operators and functions. Note that DB2 XQuery functions are a subset of the XPath 2.0 and XQuery 1.0 functions and operators. Types are based on XML Schema. There are two sets of types: the build-in types, and types imported into a query from a specific schema. The picture below shows some of build-in nodes and primitive types in a hierarchy.

XQuery_Structure.jpg

The following operators can be used in XQuery expressions ordered into groups:

Description                    Expression
Arithmetic operators +, -, *, div, mod,
General comparison operators =, !=, >, <, >=, <=
Logical operators or, and
Value comparison operators eq, ne, lt, le, gt, ge
Node comparison operators is, <<, >>

Functions are often called with the fn:  prefix; however, it does not need to be used, since fn: is the default prefix of the namespace. The following table lists the most commonly used build-in functions with simple examples: 

XQuery_Table1.jpg
XQuery_Table2.jpg
XQuery_Table3.jpg

For complete information about the data model, functions and operators, refer to the pureXML guide or  www.w3.org. 

XQuery expressions

XQuery offers several kinds of expressions, from primary expressions which are basic primitives of the language to more complex ones such as FLWOR expression. The following list provides a short overview of the most common XQuery expressions. Constructors and FLWOR expressions are covered in more details below the list.

  • Primary expressions
    • Basic expressions of the XQuery language. Includes literals, variable references, parenthesized expressions, context item expressions, and functions calls.
    • Example:
      String literal:
      "Chicken"
      Variable reference: $x = 165807
  • Path expressions
    • Locate nodes within an XML tree and are based on XPath 2.0 (briefly introduced in the previous article).
    • Example:
      /blog/articles/article[@promoted]
  • Sequence expressions
    • Using a sequence expression, you can construct, filter, and combine sequences of items. Note that sequences are never nested in XQuery. A comma operator is used to construct sequences.
    • Example:
      ($x, (10, 3), ())
  • Arithmetic expressions
    • Perform operations such as addition, subtraction, multiplication, division, and modulus on numeric, date, time, or duration values. The returning value depends on the operands. If the operands are not a valid combination, the result is a type error.
    • Example:
      $x * 1.15
  • Comparison expressions
    • XQuery provides three kinds of comparisons: value comparisons to compare single values, general comparisons to compare sequences of any length, and node comparisons to compare two nodes by their identity or document order.
    • Example:
      /blog/title eq "Chicken"
  • Logical expressions
    • Is either an and-expression or an or-expression and returns either true or false.
    • Example:
      $item = "Chicken" or $item = "Egg"
  • Conditional expressions
    • Provides if, then, and else keywords to build conditional if-then-else statements.
    • Example:
      if ($x > 5) then "Chicken" else "Egg"
  • Constructors
    • Create XML structures within a query.
  • FLWOR expressions
    • Enable computation of joins between two or more XML documents and for restructuring data.

Constructors

Constructors provide the means to create XML structures within a query. There are two types of constructors: direct, and computed. Direct constructors use XML-like notation to create nodes. For example, the following expression is a direct constructor that creates an article element.

<article aid="00010" promoted="NO">
    <title>
        Homemade pizza
    </title>
</article>

You can also use expressions within the direct constructor. Those expressions are enclosed in curly braces and are evaluated and replaced by their value, as illustrated by the following example.    

<article aid="{$id}" promoted="NO">
   {$q/title}
</article>

When $id = 00010 and $q hold the path to a title node, the output of the constructor is:

<article aid="00010" promoted="NO">
    <title>
        Homemade pizza
    </title>
</article>

Alternatively, nodes can by created by computed constructors. A computed constructor begins with a keyword that identifies the type of the node, followed by the node name (for nodes that have names) and is finished by an expression enclosed in curly braces. This expression generates the content of the node and is called the contend expression.  The following example generates exactly the same as the example with the direct constructors above.

element article {
    attribute aid {"00010"},
    attribute promoted {"NO"}
    element title {"Homemade pizza"}

FLWOR expressions

This kind of expression is useful for doing joins between two or more documents. It can be also used to restructure data. FLWOR expression, pronounced “flower,” consists of the keywords for, let, where, order by and return. The first letters of these keywords suggest the name of the expression.  

The for and let clauses generate an ordered sequence of tuples of bound variables. This is called a tuple stream. The return clause is evaluated once for every tuple. The results are concatenated as if by the comma operator. The where clause is used to filter the tuple stream. The expression of the where clause is evaluated once for each tuple in the tuple stream. The order by clause reorders the tuple stream. Both where and order by clauses are optional.

The manner in which variables are bound by for and let clauses is quite different. The for clause iterates over the items in the binding sequence, whereas the let clause binds each variable to the result of its associated expression, without iteration. Let’s consider the following examples:

let $title = ("Homemade pizza", "Eggs")
return <title>{$title}</title>

The let clause generates one tuple and the return clause is invoked for this tuple. So the output of the expression is:

<title>
  Homemade pizza Eggs
</title>

The second example contains for clause instead of let.

for $title in ("Homemade pizza", "Eggs")
return <title>{$title}</title>

The variable $title iterates over the given sequence, one tuple is generated for each binding and the return clause is invoked for each tuple. So the output of the expression in this case is

<title>
  Homemade pizza
</title>
<title>
  Eggs
</title>

The following FLWOR example returns list of tags and article titles, ordered by title, which has the corresponding tag value:

for $t in fn:distinct-values($data/blog/articles/article/tag)
order by $t
return
<tag>
    <name>{$t}</name>
    <articles> {
       for $b in $data/blog/articles/article
       where $b[tag = $t]
       order by $b/title
       return $b/title
        }
    </articles>
</tag>

To output of the expression above is:

<tag>
    <name>chicken</name>
    <articles>
        <title>Best Chicken Tikka Masala</title>
    </articles>
</tag>
<tag>
    <name>sweets</name>
    <articles>
        <title>Chocolate Ganache</title>
        <title>How to Make Besan Ladoo</title>
    </articles>
</tag> 

Conclusion

XQuery is a strongly typed language to retrieve and transform data stored in the form of XML. All XQuery expressions operate on sequences, and evaluate to sequences. XQuery shares a common data model and a set of operators and functions with XPath. FLWOR expressions offers a loose analogy to SQL’s SELECT-FROM-WHERE and are useful for doing joins between two or more documents. The article covered the minimum basics of the language. This should be sufficient for the next topic, which is SQL/XML functions. For a comprehensive guide to the XPath and XQuery language, refer to the references below. 

References

pureXML guide
www.w3.org

Recent Stories
Introduction to Db2 for z/OS System Profiles

10 questions to review and understand your active log data set configuration

DB2 for z/OS query support over FTP