Skip navigation.

XQuery Reference Guide

  Previous Next vertical dots separating previous/next from contents/index/pdf Contents Index View as PDF   Get Adobe Reader

Understanding XQuery in Liquid Data

This chapter describes the syntax for queries written in the Liquid Data implementation of the XQuery language. The Liquid Data XQuery syntax is based on the syntax described in the December 2001 draft specification "XQuery 1.0: An XML Query Language" from the W3C:

http://www.w3.org/TR/2001/WD-xquery-20011220/#nt-bnf

For more information on the versions of the XQuery and XML Schema specifications supported in Liquid Data, see XQuery and XML Specification Implementation.

The following topics are covered:

 


XQuery Syntax in Liquid Data

This section describes the syntax of an XQuery in Liquid Data. The syntax is described in blocks, and each block is defined in its own subsection. The syntax is shown as railroad diagrams. For details on how to read the railroad diagrams, see Reading the XQuery Syntax Diagrams.

Figure 2-1 shows the basic syntax for an XQuery.

Figure 2-1 Basic XQuery Syntax Diagram

Basic XQuery Syntax Diagram


 

An XQuery query expression is typically a combination of XML markup and query logic. The XQuery language allows you to mix the query logic with literal XML markup in much the same way as you can combine HTML and Java on a Java Server Page (JSP).

query_prologue

The query prologue includes zero or more namespace declarations and has the syntax shown in Figure 2-2.

Figure 2-2 Query Prologue Syntax Diagram

Query Prologue Syntax Diagram


 

namespace_declaration

A namespace declaration defines XML namespaces used in the query. Figure 2-3 shows the syntax.

Figure 2-3 Namespace Declaration Syntax Diagram

Namespace Declaration Syntax Diagram


 

where URI is a valid URI string.

The following example shows a valid namespace declaration:

namespace myspace = "http://mycorp.com/name"

query_expression

Query expressions in XQuery specify the results of a query by iterating over data, applying functions to expressions, specifying XML markup, and specifying any logic needed to get the desired result. Figure 2-4 shows the query expression syntax in Liquid Data.

Figure 2-4 Query Expression Syntax Diagram

Query Expression Syntax Diagram


 

Usage Notes

An XQuery expression can be one of many types of expressions. For details and syntax of the different types of XQuery expressions, see XQuery Expressions.

One of the main building blocks of an XQuery is the FLWR expression, as described in FLWR Expression.

Use curly braces ({}) to surround a query expression if the containing query includes XML markup (see XML Markup Expression) directly before or after the query expression.

The optional sortby expression (see sortby_expression) is used to sort the data from the XQuery expression.

If you separate query expressions with a comma (,), the results are concatenated together. Depending on the structure of your query, this can form the basis for a union-all operation.

variable_definition

XQuery variable definitions begin with the dollar sign ($) character and have the syntax shown in Figure 2-5.

Figure 2-5 Variable Definition Syntax Diagram

Variable Definition Syntax Diagram


 

For examples of variables, see Variables.

qualified_name

A qualified_name is a qualified name string in XML. The string must begin with a letter and can have any alpha-numeric character following the letter. It can also use the underscore (_), hyphen (-), and period (.) characters. For more details on qualified name strings (QName) in XML, see:

http://www.w3.org/TR/REC-xml-names/#NT-QName

Note: For improved query readability, do not qualify variable names with namespace prefixes. While it is technically permissible to use a namespace prefix in a variable name, it is more readable to omit the namespace prefix in the qualified name. Also, because the variable is local to the query (or even to a portion of the query), the namespace is not needed. For example, while a variable named $pre:order is syntactically legal, it is clearer and easier to read a variable named $order.

sortby_expression

Sorts the data in the expression preceding the sortby clause by the specified XQuery expression, either from smallest to largest (ascending) or from largest to smallest (descending). The sortby expression has the syntax shown in Figure 2-6.

Figure 2-6 Sort By Expression Syntax Diagram

Sort By Expression Syntax Diagram


 

Usage Notes

The XQuery expression that is the argument of the sortby clause must evaluate to a unit value (simple type).

If neither ascending nor descending is specified, Liquid Data defaults to ascending sort order.

To sort by multiple values, specify multiple comma-separated arguments. Multiple sort expressions will first sort by the first expression, then sort by the second expression (within groups that match on the first expression), and so on (see the second example below).

The following query sorts the results in descending order:

<root>
{
for $x in (3, 1, 2)
return
<result>
<number>{ $x }</number>
</result>
sortby(number descending)
}
</root>

This query produces the following results:

<root>
<result>
<number>3</number>
</result>
<result>
<number>2</number>
</result>
<result>
<number>1</number>
</result>
</root>

The following example query uses a sortby expression with multiple arguments:

<root>
{
for $x in (3, 1, 2)
for $y in ("b", "c", "a")
return
<NumbersAndLetters>
<number>{ $x }</number>
<letter>{ $y } </letter>
</NumbersAndLetters>
sortby (./number descending, ./letter)
}
</root>

This query produces the following results:

<root>
<NumbersAndLetters>
<number>3</number>
<letter>a</letter>
</NumbersAndLetters>
<NumbersAndLetters>
<number>3</number>
<letter>b</letter>
</NumbersAndLetters>
<NumbersAndLetters>
<number>3</number>
<letter>c</letter>
</NumbersAndLetters>
<NumbersAndLetters>
<number>2</number>
<letter>a</letter>
</NumbersAndLetters>
<NumbersAndLetters>
<number>2</number>
<letter>b</letter>
</NumbersAndLetters>
<NumbersAndLetters>
<number>2</number>
<letter>c</letter>
</NumbersAndLetters>
<NumbersAndLetters>
<number>1</number>
<letter>a</letter>
</NumbersAndLetters>
<NumbersAndLetters>
<number>1</number>
<letter>b</letter>
</NumbersAndLetters>
<NumbersAndLetters>
<number>1</number>
<letter>c</letter>
</NumbersAndLetters>
</root>

 


XQuery Expressions

Like other query languages, XQuery uses expressions as the building blocks of the query. Expressions can contain any number of expressions and can be arbitrarily complex.

An XQuery expression can have any combination of functions, operators, and other valid XQuery expressions. For a description of the functions available in Liquid Data, see Functions Reference. For details about the FLWR expression, see FLWR Expression.

This section describes the following building blocks of XQuery expressions:

XML Markup Expression

The output of an XQuery is typically an XML document. You can place XML markup in the XQuery to create the opening and closing XML tags in the result document. You can add XML markup anywhere you can add an expression. Some common places for the markup to appear in a query are at the beginning of the query body, in the return clause of a FLWR expression, and at the end of the query body.

The Liquid Data Server requires that the results a query returns are well-formed XML. In Liquid Data, queries that return XML markup that is not well-formed (for example, results that do not have a single root node) will fail with a runtime exception.

The general syntax of XML markup in an XQuery is shown in Figure 2-7.

Figure 2-7 XML Markup Expression Syntax Diagram

XML Markup Expression Syntax Diagram


 

where:

literal_text

Any text that can appear in the data portion of an XML tag.

attr

A valid XML attribute name/value pair. Can also be an expression that evaluates to a valid XML attribute name/value pair.

Usage Notes

The XQuery specification refers to XML Markup Expression as element and attribute constructors.

Curly braces ({}) are used in an XQuery to separate XQuery expressions with XML markup. If there is an XQuery expression that comes before some XML markup in a query, enclose the XQuery expression with a curly braces. If there is a closing curly brace (}) before the XML markup, there must be an opening curly brace ({) earlier in the query.

The following query includes XML markup at the beginning and end of the query and a query expression between the XML markup in the return clause:

<Founders>
{
for $x in ("Bill", "Ed", "Alfred")
return
   <founder>{$x}</founder>
}
</Founders>

FLWR Expression

The For, Let, Where, Return (FLWR) expression is an important building block of an XQuery query expression. A FLWR expression is a loop (when there is a for clause) that iterates over XML data and returns the desired results. By mixing query expressions and XML markup, the output of the FLWR expressions write out an XML document. You can create FLWR expressions within other FLWR expressions, nesting FLWR expressions to as many levels as needed. Figure 2-8 shows the basic syntax of a FLWR expression in Liquid Data.

Figure 2-8 FLWR Expression Syntax Diagram

FLWR Expression Syntax Diagram


 

Usage Notes

If you have a for or a let clause (or both, or any combination of for or let clauses), you must have a single return clause.

The XQuery Expressions in the for and let clause evaluates to a sequence of values. The FLWR expression then binds the sequence to the variable. A sequence is a set of zero or more values. For example, the sequence that contains the numbers 1, 2, and 3 can be expressed as (1, 2, 3). The sequence of values can be expressed as any XQuery expression, including PATH Expressions and expressions containing literal or derived values (from other expressions, for example).

XQuery is a declarative query language, so when you specify loops or other programming constructs in an expression, you are specifying a logical expression of the data, not necessarily the physical plan for the query to be executed. The Liquid Data server will determine the most efficient execution plan for the query that produces the results declared in the query.

Nested FLWR expressions can represents joins between data sources. For details on specifying joins, see Specifying Joins and Unions in XQuery.

for Clause

The for clause binds a series of values to a variable. The variable(s) defined in the for clause represent an item in a sequence, and the loop is evaluated for each item in the sequence. When a variable is referenced later in a FLWR expression (in the where or return clauses, for example), it evaluates to the item in the sequence corresponding to the iteration of the for loop.

For example, consider the following for clause:

for $i in (1, 2, 3)

This for clause creates a loop whose body will be evaluated three times, first for the value 1, next for the value 2, and finally for the value 3.

let Clause

The let clause binds a whole sequence to a variable. The variable is then available for use in the FLWR expression. When reading the let clause, you can read the assign string (:=) as the phrase "be bound to." For example, consider the following let clause:

let $x := (1, 2, 3)

You can read this as "let the variable named x be bound to the sequence containing the items 1, 2, and 3."

where Clause

The where clause places a condition on the for and/or let clause that precedes the where clause. A where clause can be any query expression, including another FLWR expression. The where clause typically filters the number of matches for the FLWR loop. The filter specified by the where clause can specify a join between two sources. For example, consider the following query:

<results> 
{
for $x in (1, 2, 3), $y in (2, 3, 4)
where $x eq $y
return
     <matches>{$x}</matches>
}
</results>

The where clause in this query filters (or joins) the results that match two sequences specified in the for clause. In this case, the numbers 2 and 3 match, and the query returns the following results:

<results>
     <matches>2</matches>
     <matches>3</matches>
</results>

return Clause

The return clause is evaluated for each successful (non-filtered) variable binding of the for loop. A return clause often includes XML markup combined with expressions that manipulate data. The combination of the XML markup and XQuery expressions writes out a portion of the XML result document that the query returns. For the syntax of XML markup in an XQuery expression, see XML Markup Expression.

PATH Expressions

Use PATH expressions to specify a node or a sequence of nodes in an XML tree. A PATH expression has the general syntax described in Figure 2-9 and Figure 2-11.

Note: This is only a partial syntax to highlight common PATH expression use cases in Liquid Data. For more detailed syntax of PATH expressions, see the PATH section of the XQuery specification:

http://www.w3.org/TR/2001/WD-xquery-20011220/#id-path-expressions

Figure 2-9 Partial PATH Expression Syntax Diagram

Partial PATH Expression Syntax Diagram


 

Figure 2-10 First Step of PATH Expression Syntax Diagram

First Step of PATH Expression Syntax Diagram


 

Figure 2-11 Next Step of PATH Expression Syntax Diagram

Next Step of PATH Expression Syntax Diagram


 

where:

first_step

An expression that specifies the first step of a PATH expression. See Figure 2-10 for the syntax of the first step.

next_step

An expression that specifies a step of a PATH expression. See Figure 2-11 for the syntax of a step.

function_call

An XQuery function call which specifies the step. For example, you can call the xf:document function to access many Liquid Data data sources.

variable

An variable accessible to the query. For details on variables, see Variables.

element_name

The qualified name of a node specifying a step. Precede an element name by a colon (:) if the element name is the same as an XQuery keyword (for example, :for).

attribute_name

The name of an attribute for the step (must be proceeded by the @ character).

wildcard

A wildcard (*) specifies everything in the context node. Wildcards can also be used in conjunction with namespace prefixes; the wildcard can represent either the prefix or the node names. For example, foo:* represents all nodes with the prefix foo, and *:foo represents all prefixes with a node named foo.

/

The next node in the XML tree (go down one level from this node).

//

All descendants of this node in the XML tree (go down as many levels as there are from this node).

dot (.) 

Specifies to use the current node as the step.

predicate

An XQuery Expression (see XQuery Expressions) that returns a boolean value. If the boolean evaluates to FALSE for a given value of the sequence of values produced by the preceding PATH expression, then that value is filtered from the result. If the boolean evaluates to TRUE for a given value of the sequence of values, then that value is allowed in the result. PATH expressions in the predicate are evaluated relative to the step in the tree in which the predicate occurs.

Usage Notes

You can qualify steps in a PATH expression with a predicate. Predicates in PATH expressions are surrounded by square brackets ([]).

XQuery expressions in the first step other than the ones specified in Figure 2-10 must be surrounded by parenthesis (()).

Liquid Data also supports the XPath non-abbreviated step syntax (for example, child::, descendant::, and so on).

Figure 2-12 shows some example PATH expressions and describes their meanings.

Table 2-12 PATH Expression Examples and Their Meanings 

PATH Expression

Evaluates to...

document("RTL-CUSTOMER")/db/CUSTOMER/FIRST_NAME

The FIRST_NAME child elements of CUSTOMER from the RTL-CUSTOMER relational database. The document function is used to fetch the schema for the relational database, and then the steps take you to the FIRST_NAME elements.

./number

From the current context, find the children named number. See the second example in sortby_expression for an example of this PATH expression.

document("RTL-CUSTOMER")/db/CUSTOMER/FIRST_NAME[. eq "Homer"]

The FIRST_NAME elements containing the data "Homer".

This section does not cover all of the expressions you can create with PATH expressions; there are many more complex expressions you can create with PATH expressions. For more detailed syntax and examples of PATH expressions, see the PATH section of the XQuery specification:

http://www.w3.org/TR/2001/WD-xquery-20011220/#id-path-expressions

Conditional Expressions (if-then-else)

You can create conditional expressions using the if then else construct. The conditional expression syntax is described in Figure 2-13.

Figure 2-13 Conditional Expression Syntax Diagram

Conditional Expression Syntax Diagram


 

Usage Notes

You can provide elseif logic by nesting another conditional expression as the argument of the else clause. For example:

if $a + $b lt 20
then "less than 20"
else
    if $a + $b gt 50
    then "greater than 50"
    else "between 20 and 50"

The else clause is required, but you can provide if-then logic (with no else) by specifying the empty set for the argument of the else clause. For example, the following query:

<a>
{
for $x in (1, 2), $y in (3, 4)
return
if $x + $y lt 5
then <b>{"less than 5"}</b>
else <b>{ () }</b>
}
</a>

Returns the following results:

<a>
<b>less than 5</b>
<b/>
<b/>
<b/>
</a>

You can also use the XQuery function xfext:if-then-else to provide conditional logic, as described in xfext:if-then-else.

Built-In Functions

Liquid Data has many functions available for use in queries. You can include functions in any XQuery expression. The functions take zero or more inputs and return a single output. For details (including syntax and examples) on the functions available in Liquid Data, see Functions Reference.

Constants

You can specify constant literal values in an XQuery. String constants are surrounded by double-quotation marks ("); numeric constants are not.

String Constants

You use string constants to specify strings of characters in an XQuery expression. String constants are surrounded by either single-quotation marks (') or double-quotation marks ("). The output of a string constant has the xs:string data type. Table 2-14 lists some examples of string constants.

Table 2-14 String Constants Expressions and What They Evaluate To 

Numeric Constant

Evaluates to...

"Hello there."

Hello there.

"123.45"

123.45

Numeric Constants

You can specify numeric constants by specifying a number (with or without a decimal point). You can also specify a number using exponent notation. Table 2-15 lists some examples of numeric constants.

Table 2-15 Numeric Constants Expressions and What They Evaluate To 

Numeric Constant

Evaluates to...

123

The number 123

123.45

The decimal number 123.45

12345 e -2

The double value equal to 123.45

Variables

The dollar sign character ($) specifies a variable in XQuery. The string that immediately follows the dollar sign is the variable name. You often specify variables and bind values to them in the for or let clause of a FLWR expression, and then use the variables in an expression in the return clause. For the syntax of a variable definition, see variable_definition.

Table 2-16 shows some examples of variable definitions and uses.

Table 2-16 XQuery Variable Expressions and their English Translations 

XQuery Fragment

English Translation

$x

Value if a variable named "x".

let $x := "hello"

Let the value of the variable named "x" be bound to the string "hello".

let $y := ("hello", "goodbye")

Let the value of the variable named "y" be bound to the sequence ("hello", "goodbye").

You declare variable names and bind them to values in the for or let clauses of a FLWR expression. When you declare a variable that evaluates to a sequence in the for clause, the value of the variable when referenced in the where or return clause is bound to the item in the sequence corresponding to the iteration of the loop; the variable value is not the sequence to which the variable was declared in the for clause.

For example, consider the following query that binds the variable $x in the for clause:

<Beatles>
{
for $x in ("JOHN","PAUL", "GEORGE", "RINGO")
return
<beatle>{$x}</beatle>
}
</Beatles>

This query evaluates the variable $x once for each iteration of the for loop, and in each instance the value is an item in the sequence. It returns the following result:

<Beatles>
    <beatle>JOHN</beatle>
    <beatle>PAUL</beatle>
    <beatle>GEORGE</beatle>
    <beatle>RINGO</beatle>
</Beatles>

Now consider the following query that binds the variable $x in the let clause:

<Beatles>
{
let $x := ("JOHN","PAUL", "GEORGE", "RINGO")
return
<beatle>{$x}</beatle>
}
</Beatles>

This query evaluates the variable $x only once, and the value is the sequence to which the variable is bound in the let clause. It returns the following result:

<Beatles>
    <beatle>JOHNPAULGEORGERINGO</beatle>
</Beatles>

Operators

Operators allow you to construct an expression that compares or combines expressions. Use operators to construct mathematical expressions, logic tests, and tests comparing values (for example, greater than, less than, and so on). For details (including syntax and examples) on the operators available in Liquid Data, see Comparison Operators, Logical Operators, and Numeric Operators.

Quantified Expressions

A quantified expression returns a boolean based on the comparison of two XQuery expressions. When using the construct with the keyword every, it evaluates to true if every instance of the satisfies expression is true. When using the keyword some, it evaluates to TRUE if any instance of the satisfies expression is true. Figure 2-17 shows the syntax of the quantified expression.

Figure 2-17 Quantified Expression Syntax Diagram

Quantified Expression Syntax Diagram


 

Example

The following query:

<results>
  <a>{every $y in (2, 3, 4) satisfies ($y eq 2)}</a>
</results>

returns the following results:

<results>
<a>false</a>
</results>

The reason for the false result data value in this query is because not every instance of the satisfies expression evaluates to true; only the first instance (when the variable $y is bound to the value 2) evaluates to TRUE. Therefore, the quantified expression returns false. If you substitute the keyword some for every in this query, the quantified expression will return true.

Query Parameters

Query parameters are variables whose value is supplied at query runtime. A Liquid Data query parameter begins with the string $# and has the syntax described in Figure 2-18.

Figure 2-18 Query Parameter Syntax Diagram

Query Parameter Syntax Diagram


 

The specified datatype must be a valid Liquid Data data type, as described in Data Types.

 


XQuery Comments and Join Hints

You can add comments anywhere in an XQuery. Comments are a useful means of documenting what the query is trying to accomplish. Also, the Liquid Data Server interprets certain specific comments as query compilation join hints when compiling and executing the query.

Comments

Any text, except for the hints (described below in Join Hints), between the opening and closing comment tags is considered a comment and is ignored by the Liquid Data query processor. Figure 2-19 shows the syntax for comments.

Figure 2-19 Query Comment Syntax Diagram

Query Comment Syntax Diagram


 

where:

comment_text

Any text used for a comment. The text is ignored at query compile-time and runtime.

Note: You cannot have comments within comments.

Join Hints

The Liquid Data query processor interprets join hints in a query to force certain optimizations on a query. Join hints are useful when you know something about the underlying data where one method of processing might perform better than another.

Table 2-20 describes the hints available in Liquid Data.

Table 2-20 Join Hints in Liquid Data 

Join Hint Text

Description

{--! ppright !--}

Right parameter passing join

{--! ppleft !--}

Left parameter passing join

{--! merge !--}

Merge join

{--! index !--}

Index join

To use these join hints, place them to the right of the operator in the join condition. For more details on optimizing queries and examples of using join hints, see Analyzing and Optimizing Queries in Building Queries and Data Views.

 


Specifying Joins and Unions in XQuery

There is often a need to create result documents which combine data sourced from different places, whether those places are different tables in a relational database, different files containing XML data, or any other kinds of systems containing data, including combinations of relational, XML, Web Services, and other data. You can specify joins and unions in XQuery to combine data.

The main building block for specifying a join in XQuery is a set of nested FLWR expressions. Since FLWR expressions are loops, and since XML data is structured hierarchically, you can recursively loop over XML documents, taking values from an outer loop and using them in an inner loop.

This section describes some design patterns for specifying joins in XQuery. The following topics are included:

Using Multiple For Statements to Create a Result

To specify a join between two sources in an XQuery, use a nested FLWR expression. You iterate over one of the join documents in the outer loop, then iterate over the other in the inner loop, specifying the join condition in the where clause.

The following example query iterates over the CUSTOMER element of the PB-WL document, then joins the PB-WL document with the PB_BB document where the CUSTOMER_ID values are equal (where the same CUSTOMER_ID value appears in both documents). Then it prints out the FIRST_NAME element for each CUSTOMER_ID that is in both documents.

<RESULTS>
     {
     for $x in document("PB-WL")/db/CUSTOMER
          for $z in document("PB-BB")/db/CUSTOMER
          where ($z/CUSTOMER_ID eq $x/CUSTOMER_ID)
          return
          <CUSTOMER>
               <FIRST_NAME>{ xf:data($x/FIRST_NAME) }</FIRST_NAME>
          </CUSTOMER>
     }
</RESULTS>

The basic pattern for this join is:

for_clause
    for_clause
    where_clause (with join conditions)
    return_clause (with XML markup and data)

This technique is similar to a join in SQL because it binds values in the for clauses to data source values, which is analogous to how SQL selects values from tables in the FROM clause. In the where clause of the XQuery FLWR expression, you can specify join conditions by specifying a condition where the value in the outer loop compares to the value in the inner loop. The query then returns results that satisfy these join conditions.

Note: If you want the XML markup to appear in the result document even if there are no matches found in the query (similar to an outer join in SQL), you can set up the query so there are return values associated with each part of the for clause. For an example of a query that uses this pattern, see the query in the following Hierarchical Result Document example.

Working From a Hierarchical Result Document Backwards: a Technique

One technique for building a query is to look at the shape of the result document and begin to build that result document from the innermost elements working towards the outermost elements. This technique works especially well for schemas that have complex, repeatable elements that are nested within other complex elements.

Starting with the innermost repeatable elements, place a return clause followed by the XML markup for that part of the result. Continue this process until you have all of the XML markup for the query. Next, add the rest of the FLWR expression to correspond to each return clause. Finally, complete the return clause to add the data needed for each element.

For example, consider a query that needs to display results in the following shape:

<customers>
   <Customer>*
      <name>
      <orders>*
           <orderID>
           <lineItems>*
                 <quantity>
                 <price>
                 <product>

In this case, the inner-most repeatable element is lineItems. You can build the following return clause:

            return
            <lineItems>
                 <quantity>{ }</quantity>
                 <price>{ }</price>
                 <product>{ }</product>
            </lineItems>

Continuing this to the outside of the result schema yields the following:

     return
     <Customer>
        <name>{ }</name>
        return
        {
        <orders>
            <orderID>{ }</orderID>
            return
            {
            <lineItems>
                 <quantity>{ }</quantity>
                 <price>{ }</price>
                 <product>{ }</product>
            </lineItems>
            }
        </orders>
        }
     <Customer>

Next, fill in the outermost XML markup and some syntax details (like the for statements and the outer XML markup) to yield the following:

<customers>
{
     for
     return
     <Customer>
        <name>{ }</name>
        {
        for
        return
        <orders>
            <orderID>{ }</orderID>
            {
            for
            return
            <lineItems>
                 <quantity>{ }</quantity>
                 <price>{ }</price>
                 <product>{ }</product>
            </lineItems>
            {
        </orders>
        {
     <Customer>
}
</customers>

You now have the basic structure of the query. To make the query executable, add the variable bindings for the for clauses, any join conditions or other filters in the where clause, and the query expressions to fetch the data. The following query is executable against the sample database installed with Liquid Data:

<customers>
{
    for $cust in document("PB-BB")/db/CUSTOMER
    return
    <Customer>
        <name>{ xf:data($cust/FIRST_NAME) }</name>
       {
        for $orders in document("PB-BB")/db/CUSTOMER_ORDER
        where ($cust/CUSTOMER_ID eq
            $orders/CUSTOMER_ID)
        return
        <orders>
            <orderID>{ xf:data($orders/ORDER_ID) }</orderID>
            {
                for $lineItems in                     document("PB-BB")/db/CUSTOMER_ORDER_LINE_ITEM
                where ($orders/ORDER_ID eq $lineItems/ORDER_ID)
                return
                <lineItems>
                   <quantity>{ xf:data($lineItems/QUANTITY) }</quantity>
                   <price>{ xf:data($lineItems/PRICE) }</price>
                   <product>{ xf:data($lineItems/PRODUCT_NAME) }</product>
                </lineItems>
                }
            </orders>
            }
    </Customer>
}
</customers>

Note that this example uses the xf:data function to extract just the data portion from the node specified in the PATH expressions for the order ID, quantity, price, and product. If you omit the xf:data functions, the results will include the XML tags for those pieces of data in addition to the data between the tags. For more details on the xf:data function, see xf:data.

Specifying Aggregates and Groups (Group By)

Queries that use aggregate functions (for example, xf:avg, xf:sum, xf:min, xf:max, xf:count) often compute results based on the group at which the aggregation function is calculated. For example, if you want to find the sum of products calculated for each product, the aggregate group is product. To create queries with aggregate functions that apply at a particular group (analogous to the GROUP BY clause in SQL), you must use the xf:distinct-values function for each group of the aggregate.

For example, if you want to find the sum of sales for each product (that is, the total sales for product a, the total sales for product b, and so on), then the query must first find the distinct products; then, for each distinct product, iterate through the data to calculate the sum of orders of that product.

The following query demonstrates an aggregate (sum) grouped by product:

<results> {

{-- For each distinct product --}
for $eachProduct in xf:distinct-values
          (document("PB-BB")/db/CUSTOMER_ORDER_LINE_ITEM/PRODUCT_NAME)

{-- Compute the sales for each product and bind the values to a sequence --}

let $listOfLineItemSales :=
   for $eachLineItem in document("PB-BB")/db/CUSTOMER_ORDER_LINE_ITEM
{-- This condition restricts the line items to the product --}
   where ($eachLineItem/PRODUCT_NAME eq $eachProduct)
   return {-- the Sales of the product per line item --}
$eachLineItem/QUANTITY * $eachLineItem/PRICE

return {-- Once for each product, print out the product name and add up
the sum of all items in the list of line item salessales --}
     <SalesbyProduct>
        <product_name>{ $eachProduct }</product_name>
        <sumOfSalesForProduct>{ xf:sum($listOfLineItemSales)
                              }</sumOfSalesForProduct>
</SalesbyProduct>
}
</results>

If the data included two distinct products, Product A and Product B, then the results of this query are as follows:

<results>
     <SalesByProduct>
          <product_name>Product A</product_name>
          <sumOfSalesForProduct>526.34</sumOfSalesForProduct>
     </SalesByProduct>
     <SalesByProduct>
          <product_name>Product B</product_name>
          <sumOfSalesForProduct>226.48</sumOfSalesForProduct>
     </SalesByProduct>
</results>

Specifying a Union-All Query

Use a comma character (,) to concatenate two query expressions into a single result document. For example, consider the following simple union-all query:

<RESULTS>
{
for $x in (1,2,3)
return
<number>{ $x }</number>
{-- insert a comma to specify a Union-All of the 2 query expressions --}
,
for $y in (4,5,6)
return
<number>{ $y }</number>
}
</RESULTS>

This query returns the following results:

<RESULTS>
    <number>1</number>
    <number>2</number>
    <number>3</number>
    <number>4</number>
    <number>5</number>
    <number>6</number>
</RESULTS>

The concatenated expressions are evaluated in the order they appear in the query. To break this down further, the following list describes the order in which each part of this query is evaluated:

  1. The opening tag <RESULTS> is produced.
  2. The first for loop is evaluated for the value 1, returning <number>1</number>.
  3. This first for loop evaluates for the value 2, then again for the value 3.
  4. Since the first for loop has completed all the values in the sequence $x, the query continues to the second for loop. The first iteration of the second for loop returns <number>4</number>.
  5. The second for loop evaluates for the value 5, then again for the value 6.
  6. The closing tag </RESULTS> is produced.

 


Reading the XQuery Syntax Diagrams

The XQuery syntax in this document is described using railroad diagrams. Railroad diagrams describe the language syntax in blocks. You read the diagrams from left-to-right and top-to-bottom, taking a path defined by the lines and arrows in the diagram. This section describes how to read the railroad diagrams used to define the XQuery syntax in this reference, and includes the following subsections.

Text Conventions

The following shows the conventions for text in the syntax diagrams:

Follow the Lines and Arrows Coming Into the Diagram

The syntax diagrams begin with an arrow and end with two facing arrows, as shown in Figure 2-21. From the left side of the diagram, follow the arrow to navigate through the diagram. Figure 2-21 represents a syntax block with no content. To read the diagram, start from the top line, continue on the next line when you reach the next arrow, and end at the left and right facing arrows.

Figure 2-21 Syntax Diagram Begin and end Arrows

Syntax Diagram Begin and end Arrows


 

Blocks with No Arrows Indicate Optional Content

Syntax blocks that extend above a line with no arrows indicate optional content. Follow the lines through the syntax block in one of the possible ways to form the syntax. Figure 2-22 shows a syntax block that can include either the literal text descending, the literal text ascending, or no text at all.

Figure 2-22 Optional Non-Repeatable Content Blocks

Optional Non-Repeatable Content Blocks


 

Blocks with Arrows (Loops) Indicate Repeatable Options

Syntax blocks that extend above a line with arrows indicate optional and repeatable content that can loop. Follow the lines through the syntax block in one of the possible ways to form the syntax. Figure 2-23 shows a syntax block that can include the literal text hello and, optionally, can repeat by placing a comma between instances of the literal text hello.

Figure 2-23 Optional Repeatable Content Blocks

Optional Repeatable Content Blocks


 

Therefore, the following are legal according to this syntax diagram:

The literal text echo echo is invalid according to this diagram (it is missing the comma).

 

Skip navigation bar  Back to Top Previous Next