W3C

XQuery Scripting Extension 1.0

W3C Working Draft 8 April 2010

This version:
http://www.w3.org/TR/2010/WD-xquery-sx-10-20100408
Latest version:
http://www.w3.org/TR/xquery-sx-10/
Previous versions:
http://www.w3.org/TR/2008/WD-xquery-sx-10-20081203 http://www.w3.org/TR/2008/WD-xquery-sx-10-20080328/
Editors:
John Snelson, Oracle Corporation <john.snelson@oracle.com>
Don Chamberlin, IBM Almaden Research Center, via http://www.almaden.ibm.com/cs/people/chamberlin/
Daniel Engovatov, W3C invited expert
Dana Florescu, Oracle Corporation <dana.florescu@oracle.com>
Giorgio Ghelli, University of Pisa <ghelli@di.unipi.it>
Jim Melton, Oracle Corporation <jim.melton@acm.org>
Jérôme Siméon, IBM T.J. Watson Research Center <simeon@us.ibm.com>

Abstract

This specification defines an extension to [XQuery 1.0] and [XQuery Update Facility]. Expressions can be evaluated in a specific order, with later expressions seeing the effects of the expressions that came before them. This specification introduces several new kinds of expression, including the apply, assignment, while, and exit expression, and a block expression with local variable declarations.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This is a Working Draft as described in the Process Document. It has been developed by the W3C XML Query Working Group, which is part of the XML Activity. The Working Group expects to advance this specification to Recommendation Status.

This is the last version of XQuery Scripting Extension that is aligned with XQuery Update Facility 1.0. In future versions of this document, the Working Group intends to reposition XQuery Scripting Extension 1.0 against the [XQuery 1.1] set of specifications, and remove it from the [XQuery 1.0] publication track.

No implementation report currently exists. However, a Test Suite for XQuery Scripting Extension 1.0 is under development.

This document incorporates changes made against the previous publication of the Working Draft of 3 December 2008. Changes to this document since the previous publication of the Working Draft are detailed in [G Revision Log].

Please report errors in this document using W3C's public Bugzilla system (instructions can be found at http://www.w3.org/XML/2005/04/qt-bugzilla). If access to that system is not feasible, you may send your comments to the W3C XSLT/XPath/XQuery public comments mailing list, public-qt-comments@w3.org. It will be very helpful if you include the string “[SX]” in the subject line of your report, whether made in Bugzilla or in email. Please use multiple Bugzilla entries (or, if necessary, multiple email messages) if you have more than one comment to make. Archives of the comments and responses are available at http://lists.w3.org/Archives/Public/public-qt-comments/.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1 Introduction
2 Extensions to the Processing Model
    2.1 Evaluation Order
    2.2 Snapshot and Execution Scope
    2.3 Variable Binding Revalidation
    2.4 Updating Expression Constraints
    2.5 Sequential Expressions
3 Extensions to the Static Context
    3.1 Predefined Namespace
    3.2 Query Mode
4 Extensions to the Prolog
    4.1 Assignable Global Variables
    4.2 Function Declarations
    4.3 Query Mode Option
5 New Kinds of Expressions
    5.1 Apply Expression
    5.2 Block Expressions
    5.3 Assignment Expression
    5.4 While Expression
    5.5 Exit Expression
    5.6 Query Mode Pragma
6 Changes to Existing Expressions
    6.1 Parentheses
    6.2 Function Calls
    6.3 Path Expressions
    6.4 Predicates
    6.5 Concatenation Expressions
    6.6 Direct and Computed Node Constructors
    6.7 FLWOR Expressions
    6.8 Conditional Expressions
    6.9 Quantified Expressions
    6.10 Typeswitch Expressions
    6.11 Insert, Delete, Replace, and Rename Expressions
    6.12 Transform Expressions
    6.13 Other Expressions
7 Example

Appendices

A EBNF for XQuery 1.0 Grammar with Scripting Extensions
    A.1 Terminal Symbols
    A.2 Extra-grammatical Constraints
B XML Syntax (XQueryX) for XQuery Scripting Extension 1.0
    B.1 Schema
    B.2 Stylesheet
    B.3 Example
        B.3.1 XQuery Representation
        B.3.2 XQueryX Representation
        B.3.3 Transformed XQuery Representation
C Implementation-Defined Items
D References
E Error Conditions
    E.1 New Error Codes
    E.2 Amendments to Existing Error Codes
F Glossary (Non-Normative)
G Revision Log (Non-Normative)
    G.1 Since the 3 December 2008 Working Draft
    G.2 Since the 28 March 2008 Working Draft


1 Introduction

XQuery Scripting Extension extends [XQuery 1.0], enabling it to serve as a scripting language in order to satisfy [XQuery Scripting Requirements]. A prerequisite for this extension is [XQuery Update Facility]. The following abbreviations are used in this specification: [Definition: XQUF is an abbreviation for [XQuery Update Facility].] [Definition: XQSX is an abbreviation for XQuery Scripting Extension.]

In this document, examples and material labeled as "Note" are provided for explanatory purposes and are not normative.

XQSX has the following properties:

2 Extensions to the Processing Model

Expressions in XQSX may have side-effects that are visible to subsequent expressions (according to their evaluation order). This requires a number of extensions to the [XQuery 1.0]and [XQuery Update Facility] processing model.

2.1 Evaluation Order

[Definition: XQSX defines an evaluation order on many kinds of XQuery expressions, which is the order that operand expressions must be evaluated in order to determine what side-effects are visible to later expressions.] An implementation may use any execution strategy as long as the result complies with the semantics of this ordering.

Note:

Since none of the XQuery expressions existing before XQSX has any immediate side-effects, no ordering is effectively imposed on the evaluation of any expression unless it contains one of the new sequential expressions introduced by XQSX.

2.2 Snapshot and Execution Scope

The term snapshot is defined in [XQuery Update Facility] as follows: [Definition: A snapshot is a scope within which expressions are evaluated with respect to a fixed XDM instance and updates are held pending.] A snapshot is terminated by invocation of the upd:applyUpdates operation. Unlike XQUF, XQSX permits a query to contain more than one snapshot.

[XQuery 1.0 and XPath 2.0 Functions and Operators] defines certain functions as stableFO. Stable functions such as fn:current-time and fn:doc are defined to return the same result given the same arguments within an execution scopeFO. XQSX redefines the extent of an execution scope, so that a top level query can contain many execution scopes.

In XQSX, each of the following expressions is both a snapshot and execution scope:

  • each ConcatExpr within an ApplyExpr

  • each initialization expression in a BlockVarDecl

  • the expression on the right-hand side of an AssignmentExpr

  • the expression in an ExitExpr

  • the test expression in a WhileExpr

2.3 Variable Binding Revalidation

To ensure type soundness, variable bindings are revalidated at the end of each scope to check that any updates applied have not made them invalid with repect to their declared types. It is a dynamic error [err:SXDY0003] if, after applying a pending update list (using upd:applyUpdates), the XDM instance bound to any in-scope variable does not match the static type of that variable according to SequenceType matching rules.

2.4 Updating Expression Constraints

XQSX relaxes the constraints on the placement of updating expressions, so that a non-empty XDM instance can be returned by an expression as well as a non-empty pending update list. In order to allow this, new rules to determine the category and resulting pending update list are added to every existing expression, following certain principles:

2.5 Sequential Expressions

XQSX introduces a new expression category called sequential expressions. The simple and updating expression categories introduced by XQUF are retained, but the vacuous expression category no longer has significance. Informal definitions of all the expression categories are summarized here. For normative definitions of the categories, see the "Category Rules" that are specified for each kind of expression in [5 New Kinds of Expressions] and [6 Changes to Existing Expressions].

  1. [Definition: An updating expression is an expression that can return a non-empty pending update list.] Updating expressions include insert, delete, replace, rename, and calls to updating functions, as well as certain other expressions that contain nested updating expressions. An updating expression may return a non-empty XDM instance as well as a non-empty pending update list - however note that it does not actually apply any updates.

  2. [Definition: A sequential expression is an expression that can have side effects other than constructing a new node or raising an error.] Side effects include applying updates to an XDM instance, altering the dynamic context, or affecting the flow of control. Sequential expressions include apply expressions, assignment, exit, while, and calls to sequential functions, as well as certain other expressions that contain nested sequential expressions. The side effects of a sequential expression are immediately effective and are visible to subsequent expressions. Because of their side effects, sequential expressions must be evaluated in a well-defined order. In addition to its side effects, a sequential expression may return a non-empty XDM instance, but it never returns a non-empty pending update list.

  3. [Definition: A simple expression is an expression that is neither an updating expression nor a sequential expression.] A simple expression may return an XDM instance, and it may construct a node or raise an error.

The classification of each expression into one of the above categories is performed by static analysis. For each kind of expression, XQSX provides rules that specify the required categories of the operand expressions and the category of the expression itself.

Note that simple expressions, updating expressions, and sequential expressions are disjoint categories. The kinds of values that can be returned by the various expression categories are summarized in the following table:

Expression category Can return non-empty XDM instance? Can return non-empty PUL? Can have immediate side-effects?
Simple YES NO NO
Updating YES YES NO
Sequential YES NO YES

3 Extensions to the Static Context

3.1 Predefined Namespace

XQSX adds the pair (xqsx, http://www.w3.org/2008/xquery-sx-10) as a predefined namespace to the statically known namespaces.

3.2 Query Mode

[Definition: The query mode governs the composability of updating and sequential expressions. Valid values are sequential and simple.] The default initial value of query mode is sequential, but it can be overwritten by an implementation. Query mode has a lexical scope, and can be modified at both the module and expression level.

In particular, query mode affects the category rules for [6.3 Path Expressions], [6.4 Predicates], [6.7 FLWOR Expressions], and [6.9 Quantified Expressions].

4 Extensions to the Prolog

4.1 Assignable Global Variables

[24]    VarDecl    ::=    "declare" ("unassignable"? | "assignable") "variable" "$" QName TypeDeclaration? ((":=" ExprSingle) | "external")

XQSX allows the qualifiers assignable and unassignable to be used in a Prolog variable declaration. [Definition: Prolog variables declared as assignable may have their value changed by an [5.3 Assignment Expression].] If an assignment qualifier is not used, the default is unassignable.

The semantics of assignable variables are the same as the semantics of unassignable variables, except that the static type of an assignable variable without a declared type is always item()*.

The initializing expression of a prolog variable (whether assignable or not) must be a simple expression [err:XUST0001].

4.2 Function Declarations

[26]    FunctionDecl    ::=    ("declare" ("simple"? | "updating") "function" QName "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external"))
| ("declare" "sequential" "function" QName "(" ParamList? ")" ("as" SequenceType)? (Block | "external"))
Definitions:

[Definition: A simple function is a function whose declaration specifies neither updating nor sequential. A simple function may optionally specify the keyword simple.]

[Definition: An updating function is a function whose declaration specifies the keyword updating.]

[Definition: A sequential function is a function whose declaration specifies the keyword sequential.]

Category Rules:
Semantics:

The semantics of simple functions are defined in [XQuery Update Facility] and [XQuery 1.0], and remain unchanged in XQSX.

The semantics of updating functions as originally defined in [XQuery Update Facility] are extended as follows:

The semantics of sequential functions are as follows:

  • The result of a sequential function is determined by the first [5.5 Exit Expression] encountered during evaluation of the Block. If no exit expression is encountered, the result of the function is the value returned by the Block that comprises its body.

  • If the result of a sequential function does not match its declared result type (after applying function conversion rules as specified in Section 3.1.5 Function CallsXQ), a type error is raised [err:XPTY0004]XQ. The default result type of a sequential function is item()*.

  • If a sequential function is declared external, its implementation is outside the XQuery environment. The means by which parameters are passed to an external function and its result is returned to the calling expression are implementation-defined. An external sequential function may not return a non-empty pending update list [err:SXDY0004].

4.3 Query Mode Option

[13]    OptionDecl    ::=    "declare" "option" QName StringLiteral

XQSX defines the QName xqsx:query-mode as a well-known option name for use in an OptionDecl, which sets the query mode in the static context for the module to the value specified. A static error is raised [err:SXST0009] if the value for a xqsx:query-mode option is not either sequential or simple.

Implementations of XQSX must recognize the option namespace URI http://www.w3.org/2008/xquery-sx-10, and the option xqsx:query-mode.

5 New Kinds of Expressions

XQSX extends the XQuery 1.0 syntax by adding several new kinds of expressions. The effect of these new expressions on the XQuery grammar is as follows:

[31]    Expr    ::=    ApplyExpr
[32]    ApplyExpr    ::=    ConcatExpr (";" (ConcatExpr ";")*)?
[33]    ConcatExpr    ::=    ExprSingle ("," ExprSingle)*
[34]    ExprSingle    ::=    FLWORExpr
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| InsertExpr
| DeleteExpr
| RenameExpr
| ReplaceExpr
| TransformExpr
| BlockExpr
| AssignmentExpr
| ExitExpr
| WhileExpr
| OrExpr

5.1 Apply Expression

[32]    ApplyExpr    ::=    ConcatExpr (";" (ConcatExpr ";")*)?
Category Rules:

[Definition: An apply expression is a list of semicolon-terminated ConcatExpr productions, called operand expressions. An ApplyExpr consisting of a single ConcatExpr with no semicolon is not an apply expression.] An apply expression is a sequential expression.

The operands of the apply expression may be an expression of any category.

Semantics:

The operand expressions of an apply expression are evaluated in the order they appear. After the evaluation of each operand expression, the pending update list returned by the expression is applied (by upd:applyUpdates). The XDM instance returned by all expressions other than the last one is discarded. The side effects of each expression are visible during the evaluation of subsequent expressions.

The result of the apply expression is the XDM instance returned by the last operand expression, and an empty pending update list.

5.2 Block Expressions

[153]    BlockExpr    ::=    "block" Block
[154]    Block    ::=    "{" BlockDecls BlockBody "}"
[155]    BlockDecls    ::=    (BlockVarDecl ";")*
[156]    BlockVarDecl    ::=    "declare" "$" VarName TypeDeclaration? (":=" ExprSingle)? ("," "$" VarName TypeDeclaration? (":=" ExprSingle)?)*
[157]    BlockBody    ::=    Expr
Category Rules:

[Definition: The expression on the right-hand side of a block variable declaration is called an initializing expression.] Initializing expressions may be in any category.

Note:

Block variable declarations, unlike Prolog variable declarations, permit their initializing expressions to be updating or sequential expressions.

If a BlockExpr contains initializing expressions that are either updating or sequential expression, then the BlockExpr is a sequential expression. In this case the BlockBody must be either a simple or sequential expression, otherwise a static error [err:SXST0002] is raised.

If a BlockExpr only contains initializing expressions that are simple expressions (or contains no initializing expressions), then the BlockBody may be an expression of any category. In this case the BlockExpr has the same category as the BlockBody.

Semantics:

A block consists of zero or more block variable declarations followed by a body. Each block variable declaration defines a modifiable local variable whose scope is the remainder of the block (not including its initializing expression). The variable defined in a block variable declaration occludes (hides) any variable of the same name that is in scope at the location where the block appears.

It is a static error [err:SXST0005] if two or more variables declared in the same block have the same expanded QName.

The type of each declared variable is added to in-scope variables in the static context. If no explicit type is declared, the type of the variable is item()*. If a variable has both an explicit type declaration and an initializing expression, the value of the initializing expression must match the declared type according to SequenceType matching rules; otherwise a type error is raised [err:XPTY0004]XQ.

The block variable declarations are evaluated in the order written. The block variable declaration evaluates its initializing expression and adds the resulting XDM instance to the variable values in the dynamic context. Any pending update list returned is applied using upd:applyUpdates. If no initializing expression is present, the variable has no initial value. A reference to a variable, other than on the left-hand side of an assignment expression, is an error if the variable has no value in variable values when the reference is evaluated [err:SXTY0006].

After all the block variable declarations have been evaluated, the BlockBody expression is evaluated. The result of the block expression is the XDM instance and pending update list returned by the BlockBody.

5.3 Assignment Expression

[158]    AssignmentExpr    ::=    "$" VarName ":=" ExprSingle
Category Rules:

An assignment expression is a sequential expression.

Semantics:

The variable on the left-hand side of the assignment must have been declared in one of the following ways, otherwise a static error [err:SXST0007] is raised:

  • By a block variable declaration

  • As a parameter to a sequential function

  • By a variable declaration in the Prolog declared as assignable

In all cases the variable must be in the in-scope variables, otherwise a static error is raised [err:XPST0008]XQ.

Note:

Variables bound in FLWOR, typeswitch, or quantified expressions may not appear on the left-hand side of an assignment.

The expression on the right-hand side is evaluated, resulting in an XDM instance and a pending update list.

If the XDM instance returned by the expression on the right-hand side does not match the declared type of the variable according to SequenceType matching rules, a type error is raised [err:XPTY0004]XQ. If the types match, the XDM instance returned by the expression is bound to the variable (added to variable values in the dynamic context.)

The pending update list returned by the expression on the right-hand side is applied using upd:applyUpdates.

The result of an Assignment Expression is an empty XDM instance and an empty pending update list.

5.4 While Expression

[160]    WhileExpr    ::=    "while" "(" ExprSingle ")" WhileBody
[161]    WhileBody    ::=    Block
Category Rules:

[Definition: The expression enclosed in the parentheses of a while expression is called a test expression.] The test expression may be in any category.

A static error [err:SXST0002] is raised if the WhileBody is an updating expression.

A while expression is a sequential expression.

Semantics:

The while expression is used for conditional iteration. It is evaluated as follows:

The test expression is evaluated, resulting in an XDM instance and a pending update list. The pending update list returned by the test expression is applied using upd:applyUpdates.

If the effective Boolean value of the test expression is false, the block is not evaluated. If the effective Boolean value of the test expression is true, the block is evaluated repeatedly. Each evaluation of the block may cause side effects that affect the result of re-evaluating the test expression. The test expression is re-evaluated after each evaluation of the block. This process continues until the effective Boolean value of the test expression is evaluated to be false.

The result of a while expression is an empty XDM instance and an empty pending update list.

Example:

In the following query, a while expression is used to compute a sequence containing all the Fibonacci numbers that are less than 100.

block {
  declare $a as xs:integer := 0;
  declare $b as xs:integer := 1;  
  declare $c as xs:integer := $a + $b;
  declare $fibseq as xs:integer* := ($a, $b);
 
  while ($c < 100) { 
     $fibseq := ($fibseq, $c);
     $a := $b;
     $b := $c;
     $c := $a + $b;
  };

  $fibseq;
}

5.5 Exit Expression

[159]    ExitExpr    ::=    "exit" "returning" ExprSingle
Category Rules:

The operand of an exit expression may be an expression of any category.

An exit expression is a sequential expression.

Semantics:

An exit expression serves to define the result of the enclosing function or query body.

The operand expression of the exit expression is evaluated, resulting in an XDM instance and a pending update list. The pending update list returned by the operand expression is applied using upd:applyUpdates.

If an exit expression is evaluated within the body of a function, further evaluation of the function body is interrupted and the XDM instance returned by the operand expression is returned as the result of the function call.

If an exit expression is evaluated within a query body (i.e., not within the body of a function), further evaluation of the query is interrupted and the XDM instance returned by the operand expression is returned as the result of the query.

Note:

An exit expression in a block terminates evaluation of the enclosing function body or query, not just the immediately enclosing block.

5.6 Query Mode Pragma

[67]    ExtensionExpr    ::=    Pragma+ "{" Expr? "}"
[68]    Pragma    ::=    "(#" S? QName (S PragmaContents)? "#)"
[69]    PragmaContents    ::=    (Char* - (Char* '#)' Char*))

XQSX defines the QName xqsx:query-mode as a well-known pragma name for use in an ExtensionExpr, which sets the query mode in the static context for the enclosed expression to the value specified. A static error is raised [err:SXST0009] if the value for a xqsx:query-mode pragma is not either sequential or simple.

Implementations of XQSX must recognize the pragma namespace URI http://www.w3.org/2008/xquery-sx-10, and the pragma name xqsx:query-mode.

6 Changes to Existing Expressions

XQSX imposes new category rules, evaluation order and additional semantics on top of existing [XQuery 1.0] and [XQuery Update Facility] expressions, detailed in this section.

6.1 Parentheses

[91]    ParenthesizedExpr    ::=    "(" Expr? ")"
Category Rules:

An expression of any category may be enclosed in parentheses; the resulting expression has the same category as the original expression. An empty parenthesized expression ( ) is a simple expression.

6.2 Function Calls

[95]    FunctionCall    ::=    QName "(" (ExprSingle ("," ExprSingle)*)? ")"
Category Rules:

If the function called is a simple function, the argument expressions can either be all simple and updating expressions, or all simple and sequential expressions. If the argument expressions contain an updating expression then the function call is an updating expression, if they contain a sequential expression then the function call is a sequential expression, otherwise it is a simple expression.

If the function called is an updating function, the argument expressions must be simple expressions or updating expressions. The function call is an updating expression.

If the function called is a sequential function, the argument expressions must be simple expressions or sequential expressions . The function call expression is a sequential expression.

If the arguments of a function call violate the category rules for the function's category, [err:SXST0002] is raised.

Evaluation Order:

Argument expressions are evaluated from left to right, then the function is invoked.

Additional Semantics:

The pending update lists returned by the argument expressions are merged with the pending update list returned by the function itself by calling upd:mergeUpdates.

6.3 Path Expressions

[70]    PathExpr    ::=    ("/" RelativePathExpr?)
| ("//" RelativePathExpr)
| RelativePathExpr
[71]    RelativePathExpr    ::=    StepExpr (("/" | "//") StepExpr)*
Category Rules:

The category of a path expression is determined by the following rules:

Evaluation Order:

StepExpr are evaluated in order from left to right.

Additional Semantics:

The pending update lists returned by each of the StepExpr are merged by calling upd:mergeUpdates, and returned as part of the result of the path expression.

6.4 Predicates

[73]    AxisStep    ::=    (ReverseStep | ForwardStep) PredicateList
[83]    FilterExpr    ::=    PrimaryExpr PredicateList
[84]    PredicateList    ::=    Predicate*
[85]    Predicate    ::=    "[" Expr "]"
Category Rules:

The category of a FilterExpr or AxisStep is determined by the following rules:

Evaluation Order:

First the reverse step, forward step or primary expression is evaluated, then predicates are evaluated from left to right. Each predicate expression must be evaluated to completion before the next is evaluated.

Additional Semantics:

The pending update list returned by the primary expression is merged with the pending update lists returned by the predicate expressions by calling upd:mergeUpdates. The resulting pending update list is returned as part of the result of the FilterExpr or AxisStep.

6.5 Concatenation Expressions

[33]    ConcatExpr    ::=    ExprSingle ("," ExprSingle)*
Category Rules:

The category of a concatenation expression is determined by the following rules:

Evaluation Order:

Operand expressions are evaluated once, from left to right. Side effects of each sequential operand expression are visible to subsequent operand expressions.

Additional Semantics:

The concatenation expression evaluates each of its operands and concatenates the resulting XDM instances and pending update lists, in order. Pending update lists are concatenated by the upd:mergeUpdates operation.

6.6 Direct and Computed Node Constructors

[98]    DirElemConstructor    ::=    "<" QName DirAttributeList ("/>" | (">" DirElemContent* "</" QName S? ">"))
[99]    DirAttributeList    ::=    (S (QName S? "=" S? DirAttributeValue)?)*
[109]    CDataSection    ::=    "<![CDATA[" CDataSectionContents "]]>"
[107]    DirPIConstructor    ::=    "<?" PITarget (S DirPIContents)? "?>"
[105]    DirCommentConstructor    ::=    "<!--" DirCommentContents "-->"
[113]    CompElemConstructor    ::=    "element" (QName | ("{" Expr "}")) "{" ContentExpr? "}"
[115]    CompAttrConstructor    ::=    "attribute" (QName | ("{" Expr "}")) "{" Expr? "}"
[112]    CompDocConstructor    ::=    "document" "{" Expr "}"
[116]    CompTextConstructor    ::=    "text" "{" Expr "}"
[118]    CompPIConstructor    ::=    "processing-instruction" (NCName | ("{" Expr "}")) "{" Expr? "}"
[117]    CompCommentConstructor    ::=    "comment" "{" Expr "}"
Category Rules:

The category of a node constructor is determined by the following rules:

Evaluation Order:
  1. The name expression is evaluated (computed element/attribute/processing-instruction constructors only).

  2. The direct attribute constructors are evaluated from left to right (direct element constructors only).

  3. The child or value expressions are evaluated from left to right.

Additional Semantics:

The pending update lists from each operand expression are concatenated by the upd:mergeUpdates operation, producing the resulting pending update list.

6.7 FLWOR Expressions

[35]    FLWORExpr    ::=    (ForClause | LetClause)+ WhereClause? OrderByClause? "return" ExprSingle
[36]    ForClause    ::=    "for" "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle ("," "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle)*
[37]    PositionalVar    ::=    "at" "$" VarName
[38]    LetClause    ::=    "let" "$" VarName TypeDeclaration? ":=" ExprSingle ("," "$" VarName TypeDeclaration? ":=" ExprSingle)*
[39]    WhereClause    ::=    "where" ExprSingle
[40]    OrderByClause    ::=    (("order" "by") | ("stable" "order" "by")) OrderSpecList
[41]    OrderSpecList    ::=    OrderSpec ("," OrderSpec)*
[42]    OrderSpec    ::=    ExprSingle OrderModifier
[43]    OrderModifier    ::=    ("ascending" | "descending")? ("empty" ("greatest" | "least"))? ("collation" URILiteral)?
Category Rules:

The for, let, where, and order by clauses can either be all simple and updating expressions, or all simple and sequential expressions.

Evaluation Order:
  • For Clause: The associated expression is evaluated first to produce the binding sequnce, then the next clause is evaluated once for each item in the binding sequence. Any side effects in the associated expression are visible to the evaluation of the next clause.

  • Let Clause: The associated expression is evaluated first to produce the binding sequnce, then the next clause is evaluated. Any side effects in the associated expression are visible to the evaluation of the next clause.

  • Where Clause: The where expression is evaluated once, then the next clause is evaluated. Any side effects in the where expression are visible to the evaluation of the next clause.

  • Order By Clause: The orderspecs are evaluated from left to right on each tuple in the tuple stream. The tuple stream is reordered, then the next clause is evaluated.

  • Return Clause: The return expresion is evaluated once.

Additional Semantics:

The result of a FLWOR expression is the concatenation of the XDM instances or pending update lists returned by successive evaluations of the return clause in evaluation order, as well as the pending update lists returned by any of the other FLWOR clauses. Pending update lists are concatenated by the upd:mergeUpdates operation.

6.8 Conditional Expressions

[47]    IfExpr    ::=    "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle
Category Rules:

The test, then and else expressions can be of any type. An error [err:SXST0002] is raised if one of the expressions is updating and another is sequential.

Evaluation Order:

The test expression is evaluated first. Next either the then expression or the else expression (but not both) is evaluated.

Additional Semantics:

The pending update list returned by the conditional expression is calculated by merging the pending update lists from the test expression and the executed branch of the conditional expression using upd:mergeUpdates.

6.9 Quantified Expressions

[44]    QuantifiedExpr    ::=    ("some" | "every") "$" VarName TypeDeclaration? "in" ExprSingle ("," "$" VarName TypeDeclaration? "in" ExprSingle)* "satisfies" ExprSingle
Category Rules:

The category of a quantified expression is determined by the following rules:

Evaluation Order:

The quantified expression clauses are initially evaluated as specified by [XQuery 1.0], generating a tuple stream. Then the satisfies clause is evaluated once for each tuple in the tuple stream, in order. If the satisfies clause contains a sequential expression, the side effects of each iteration are visible to subsequent evaluations of the return clause.

Additional Semantics:

The pending update list returned by the quantified expression is calculated by merging the pending update lists from the quantified expression clauses and the satisfies expression using upd:mergeUpdates.

6.10 Typeswitch Expressions

[45]    TypeswitchExpr    ::=    "typeswitch" "(" Expr ")" CaseClause+ "default" ("$" VarName)? "return" ExprSingle
Category Rules:

The operand, case and default expressions can be of any type. An error [err:SXST0002] is raised if one of the expressions is updating and another is sequential.

Evaluation Order:

The operand expression is evaluated first. Then, exactly one of the return expressions is evaluated.

Additional Semantics:

The pending update list returned by the typeswitch expression is calculated by merging the pending update lists from the operand expression and the executed branch of the typeswitch expression using upd:mergeUpdates.

6.11 Insert, Delete, Replace, and Rename Expressions

[145]    InsertExpr    ::=    "insert" ("node" | "nodes") SourceExpr InsertExprTargetChoice TargetExpr
[144]    InsertExprTargetChoice    ::=    (("as" ("first" | "last"))? "into")
| "after"
| "before"
[146]    DeleteExpr    ::=    "delete" ("node" | "nodes") TargetExpr
[147]    ReplaceExpr    ::=    "replace" ("value" "of")? "node" TargetExpr "with" ExprSingle
[148]    RenameExpr    ::=    "rename" "node" TargetExpr "as" NewNameExpr
[149]    SourceExpr    ::=    ExprSingle
[150]    TargetExpr    ::=    ExprSingle
[151]    NewNameExpr    ::=    ExprSingle
Category Rules:

Insert, delete, replace, and rename expressions are updating expressions, and are extended to accept both updating and simple expressions as their operands. It is a static error [err:SXST0002] for the operand of one of these expressions to be a sequential expression.

Evaluation Order:

Order of evaluation for insert, delete, replace, and rename expressions is irrelevent since their operands cannot be sequential expressions.

Additional Semantics:

The pending update list returned by insert, delete, replace, and rename expressions is calculated by merging the pending update lists from the operands of the expression and the pending update list produced by the expression itself using upd:mergeUpdates.

6.12 Transform Expressions

[152]    TransformExpr    ::=    "copy" "$" VarName ":=" ExprSingle ("," "$" VarName ":=" ExprSingle)* "modify" ExprSingle "return" ExprSingle
Category Rules:

The copy, modify and return clauses of a transform expression can be of any type. An error [err:SXST0002] is raised if one of the copy or return clauses is updating and either the copy, modify or return clauses is sequential.

Evaluation Order:

Copy clauses are evaluated in order, then the modify expression is evaluated. Finally the return clause is evaluated.

Additional Semantics:

The semantics of a transform expression as defined in Section 2.4.5 TransformXU are extended as follows:

6.13 Other Expressions

All expressions not listed above are extended as follows. This includes the following kinds of expressions:

  • Range expressions

  • Union, intersect, and except expressions

  • Arithmetic, comparison, and logical expressions

  • Ordered and unordered expressions

  • Instance of, cast, castable, and treat expressions

  • Validate expressions

  • Extension expressions (pragmas)

Category Rules:

All other expressions are extended to accept any type of expressions as their operands. An error [err:SXST0002] is raised if one of the operands is updating and another is sequential. If an operand of the expression is updating then the expression itself is updating, if an operand is sequential then the expression itself is sequential, otherwise it is simple.

Evaluation Order:

Operand expressions are evaluated once, from left to right.

Additional Semantics:

The pending update list returned by any other expression is calculated by merging the pending update lists from the operands of that expression using upd:mergeUpdates.

7 Example

The following function returns true or false according to whether its parameter is a known user name, and logs the event:

declare sequential function validate-and-log($username as xs:string) 
     as xs:boolean {
        declare $log as document-node() := fn:doc("log.xml"); 
        declare $entry as element() :=
           <access-attempt>
              <timestamp>{fn:current-dateTime()}</timestamp>
              <user-name>{$username}</user-name>
              <access-allowed/>
           </access-attempt> ;
        declare $result as xs:boolean;
        if ($username = doc("users.xml")/current-users/user/name )
        then (
           replace value of node $entry/access-allowed with "Yes";
           $result := true();
        ) else (
           replace value of node $entry/access-allowed with "No";
           $result := false();
        );
        insert node $entry as last into $log; 
        fn:put($log, "log.xml"); 
        exit returning $result;
} 

A EBNF for XQuery 1.0 Grammar with Scripting Extensions

The EBNF in this document and in this section is aligned with the current XML Query 1.0 grammar (see [XQuery 1.0]).

[1]    Module    ::=    VersionDecl? (LibraryModule | MainModule)
[2]    VersionDecl    ::=    "xquery" "version" StringLiteral ("encoding" StringLiteral)? Separator
[3]    MainModule    ::=    Prolog QueryBody
[4]    LibraryModule    ::=    ModuleDecl Prolog
[5]    ModuleDecl    ::=    "module" "namespace" NCName "=" URILiteral Separator
[6]    Prolog    ::=    ((DefaultNamespaceDecl | Setter | NamespaceDecl | Import) Separator)* ((VarDecl | FunctionDecl | OptionDecl) Separator)*
[7]    Setter    ::=    BoundarySpaceDecl | DefaultCollationDecl | BaseURIDecl | ConstructionDecl | OrderingModeDecl | EmptyOrderDecl | RevalidationDecl | CopyNamespacesDecl
[8]    Import    ::=    SchemaImport | ModuleImport
[9]    Separator    ::=    ";"
[10]    NamespaceDecl    ::=    "declare" "namespace" NCName "=" URILiteral
[11]    BoundarySpaceDecl    ::=    "declare" "boundary-space" ("preserve" | "strip")
[12]    DefaultNamespaceDecl    ::=    "declare" "default" ("element" | "function") "namespace" URILiteral
[13]    OptionDecl    ::=    "declare" "option" QName StringLiteral
[14]    OrderingModeDecl    ::=    "declare" "ordering" ("ordered" | "unordered")
[15]    EmptyOrderDecl    ::=    "declare" "default" "order" "empty" ("greatest" | "least")
[16]    CopyNamespacesDecl    ::=    "declare" "copy-namespaces" PreserveMode "," InheritMode
[17]    PreserveMode    ::=    "preserve" | "no-preserve"
[18]    InheritMode    ::=    "inherit" | "no-inherit"
[19]    DefaultCollationDecl    ::=    "declare" "default" "collation" URILiteral
[20]    BaseURIDecl    ::=    "declare" "base-uri" URILiteral
[21]    SchemaImport    ::=    "import" "schema" SchemaPrefix? URILiteral ("at" URILiteral ("," URILiteral)*)?
[22]    SchemaPrefix    ::=    ("namespace" NCName "=") | ("default" "element" "namespace")
[23]    ModuleImport    ::=    "import" "module" ("namespace" NCName "=")? URILiteral ("at" URILiteral ("," URILiteral)*)?
[24]    VarDecl    ::=    "declare" ("unassignable"? | "assignable") "variable" "$" QName TypeDeclaration? ((":=" ExprSingle) | "external")
[25]    ConstructionDecl    ::=    "declare" "construction" ("strip" | "preserve")
[26]    FunctionDecl    ::=    ("declare" ("simple"? | "updating") "function" QName "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external"))
| ("declare" "sequential" "function" QName "(" ParamList? ")" ("as" SequenceType)? (Block | "external"))
[27]    ParamList    ::=    Param ("," Param)*
[28]    Param    ::=    "$" QName TypeDeclaration?
[29]    EnclosedExpr    ::=    "{" Expr "}"
[30]    QueryBody    ::=    Expr
[31]    Expr    ::=    ApplyExpr
[32]    ApplyExpr    ::=    ConcatExpr (";" (ConcatExpr ";")*)?
[33]    ConcatExpr    ::=    ExprSingle ("," ExprSingle)*
[34]    ExprSingle    ::=    FLWORExpr
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| InsertExpr
| DeleteExpr
| RenameExpr
| ReplaceExpr
| TransformExpr
| BlockExpr
| AssignmentExpr
| ExitExpr
| WhileExpr
| OrExpr
[35]    FLWORExpr    ::=    (ForClause | LetClause)+ WhereClause? OrderByClause? "return" ExprSingle
[36]    ForClause    ::=    "for" "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle ("," "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle)*
[37]    PositionalVar    ::=    "at" "$" VarName
[38]    LetClause    ::=    "let" "$" VarName TypeDeclaration? ":=" ExprSingle ("," "$" VarName TypeDeclaration? ":=" ExprSingle)*
[39]    WhereClause    ::=    "where" ExprSingle
[40]    OrderByClause    ::=    (("order" "by") | ("stable" "order" "by")) OrderSpecList
[41]    OrderSpecList    ::=    OrderSpec ("," OrderSpec)*
[42]    OrderSpec    ::=    ExprSingle OrderModifier
[43]    OrderModifier    ::=    ("ascending" | "descending")? ("empty" ("greatest" | "least"))? ("collation" URILiteral)?
[44]    QuantifiedExpr    ::=    ("some" | "every") "$" VarName TypeDeclaration? "in" ExprSingle ("," "$" VarName TypeDeclaration? "in" ExprSingle)* "satisfies" ExprSingle
[45]    TypeswitchExpr    ::=    "typeswitch" "(" Expr ")" CaseClause+ "default" ("$" VarName)? "return" ExprSingle
[46]    CaseClause    ::=    "case" ("$" VarName "as")? SequenceType "return" ExprSingle
[47]    IfExpr    ::=    "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle
[48]    OrExpr    ::=    AndExpr ( "or" AndExpr )*
[49]    AndExpr    ::=    ComparisonExpr ( "and" ComparisonExpr )*
[50]    ComparisonExpr    ::=    RangeExpr ( (ValueComp
| GeneralComp
| NodeComp) RangeExpr )?
[51]    RangeExpr    ::=    AdditiveExpr ( "to" AdditiveExpr )?
[52]    AdditiveExpr    ::=    MultiplicativeExpr ( ("+" | "-") MultiplicativeExpr )*
[53]    MultiplicativeExpr    ::=    UnionExpr ( ("*" | "div" | "idiv" | "mod") UnionExpr )*
[54]    UnionExpr    ::=    IntersectExceptExpr ( ("union" | "|") IntersectExceptExpr )*
[55]    IntersectExceptExpr    ::=    InstanceofExpr ( ("intersect" | "except") InstanceofExpr )*
[56]    InstanceofExpr    ::=    TreatExpr ( "instance" "of" SequenceType )?
[57]    TreatExpr    ::=    CastableExpr ( "treat" "as" SequenceType )?
[58]    CastableExpr    ::=    CastExpr ( "castable" "as" SingleType )?
[59]    CastExpr    ::=    UnaryExpr ( "cast" "as" SingleType )?
[60]    UnaryExpr    ::=    ("-" | "+")* ValueExpr
[61]    ValueExpr    ::=    ValidateExpr | PathExpr | ExtensionExpr
[62]    GeneralComp    ::=    "=" | "!=" | "<" | "<=" | ">" | ">="
[63]    ValueComp    ::=    "eq" | "ne" | "lt" | "le" | "gt" | "ge"
[64]    NodeComp    ::=    "is" | "<<" | ">>"
[65]    ValidateExpr    ::=    "validate" ValidationMode? "{" Expr "}"
[66]    ValidationMode    ::=    "lax" | "strict"
[67]    ExtensionExpr    ::=    Pragma+ "{" Expr? "}"
[68]    Pragma    ::=    "(#" S? QName (S PragmaContents)? "#)" /* ws: explicitXQ */
[69]    PragmaContents    ::=    (Char* - (Char* '#)' Char*))
[70]    PathExpr    ::=    ("/" RelativePathExpr?)
| ("//" RelativePathExpr)
| RelativePathExpr
/* gn: leading-lone-slashXQ */
[71]    RelativePathExpr    ::=    StepExpr (("/" | "//") StepExpr)*
[72]    StepExpr    ::=    FilterExpr | AxisStep
[73]    AxisStep    ::=    (ReverseStep | ForwardStep) PredicateList
[74]    ForwardStep    ::=    (ForwardAxis NodeTest) | AbbrevForwardStep
[75]    ForwardAxis    ::=    ("child" "::")
| ("descendant" "::")
| ("attribute" "::")
| ("self" "::")
| ("descendant-or-self" "::")
| ("following-sibling" "::")
| ("following" "::")
[76]    AbbrevForwardStep    ::=    "@"? NodeTest
[77]    ReverseStep    ::=    (ReverseAxis NodeTest) | AbbrevReverseStep
[78]    ReverseAxis    ::=    ("parent" "::")
| ("ancestor" "::")
| ("preceding-sibling" "::")
| ("preceding" "::")
| ("ancestor-or-self" "::")
[79]    AbbrevReverseStep    ::=    ".."
[80]    NodeTest    ::=    KindTest | NameTest
[81]    NameTest    ::=    QName | Wildcard
[82]    Wildcard    ::=    "*"
| (NCName ":" "*")
| ("*" ":" NCName)
/* ws: explicitXQ */
[83]    FilterExpr    ::=    PrimaryExpr PredicateList
[84]    PredicateList    ::=    Predicate*
[85]    Predicate    ::=    "[" Expr "]"
[86]    PrimaryExpr    ::=    Literal | VarRef | ParenthesizedExpr | ContextItemExpr | FunctionCall | OrderedExpr | UnorderedExpr | Constructor
[87]    Literal    ::=    NumericLiteral | StringLiteral
[88]    NumericLiteral    ::=    IntegerLiteral | DecimalLiteral | DoubleLiteral
[89]    VarRef    ::=    "$" VarName
[90]    VarName    ::=    QName
[91]    ParenthesizedExpr    ::=    "(" Expr? ")"
[92]    ContextItemExpr    ::=    "."
[93]    OrderedExpr    ::=    "ordered" "{" Expr "}"
[94]    UnorderedExpr    ::=    "unordered" "{" Expr "}"
[95]    FunctionCall    ::=    QName "(" (ExprSingle ("," ExprSingle)*)? ")" /* gn: sx-reserved-function-names */
/* gn: parensXQ */
[96]    Constructor    ::=    DirectConstructor
| ComputedConstructor
[97]    DirectConstructor    ::=    DirElemConstructor
| DirCommentConstructor
| DirPIConstructor
[98]    DirElemConstructor    ::=    "<" QName DirAttributeList ("/>" | (">" DirElemContent* "</" QName S? ">")) /* ws: explicitXQ */
[99]    DirAttributeList    ::=    (S (QName S? "=" S? DirAttributeValue)?)* /* ws: explicitXQ */
[100]    DirAttributeValue    ::=    ('"' (EscapeQuot | QuotAttrValueContent)* '"')
| ("'" (EscapeApos | AposAttrValueContent)* "'")
/* ws: explicitXQ */
[101]    QuotAttrValueContent    ::=    QuotAttrContentChar
| CommonContent
[102]    AposAttrValueContent    ::=    AposAttrContentChar
| CommonContent
[103]    DirElemContent    ::=    DirectConstructor
| CDataSection
| CommonContent
| ElementContentChar
[104]    CommonContent    ::=    PredefinedEntityRef | CharRef | "{{" | "}}" | EnclosedExpr
[105]    DirCommentConstructor    ::=    "<!--" DirCommentContents "-->" /* ws: explicitXQ */
[106]    DirCommentContents    ::=    ((Char - '-') | ('-' (Char - '-')))* /* ws: explicitXQ */
[107]    DirPIConstructor    ::=    "<?" PITarget (S DirPIContents)? "?>" /* ws: explicitXQ */
[108]    DirPIContents    ::=    (Char* - (Char* '?>' Char*)) /* ws: explicitXQ */
[109]    CDataSection    ::=    "<![CDATA[" CDataSectionContents "]]>" /* ws: explicitXQ */
[110]    CDataSectionContents    ::=    (Char* - (Char* ']]>' Char*)) /* ws: explicitXQ */
[111]    ComputedConstructor    ::=    CompDocConstructor
| CompElemConstructor
| CompAttrConstructor
| CompTextConstructor
| CompCommentConstructor
| CompPIConstructor
[112]    CompDocConstructor    ::=    "document" "{" Expr "}"
[113]    CompElemConstructor    ::=    "element" (QName | ("{" Expr "}")) "{" ContentExpr? "}"
[114]    ContentExpr    ::=    Expr
[115]    CompAttrConstructor    ::=    "attribute" (QName | ("{" Expr "}")) "{" Expr? "}"
[116]    CompTextConstructor    ::=    "text" "{" Expr "}"
[117]    CompCommentConstructor    ::=    "comment" "{" Expr "}"
[118]    CompPIConstructor    ::=    "processing-instruction" (NCName | ("{" Expr "}")) "{" Expr? "}"
[119]    SingleType    ::=    AtomicType "?"?
[120]    TypeDeclaration    ::=    "as" SequenceType
[121]    SequenceType    ::=    ("empty-sequence" "(" ")")
| (ItemType OccurrenceIndicator?)
[122]    OccurrenceIndicator    ::=    "?" | "*" | "+" /* gn: occurrence-indicatorsXQ */
[123]    ItemType    ::=    KindTest | ("item" "(" ")") | AtomicType
[124]    AtomicType    ::=    QName
[125]    KindTest    ::=    DocumentTest
| ElementTest
| AttributeTest
| SchemaElementTest
| SchemaAttributeTest
| PITest
| CommentTest
| TextTest
| AnyKindTest
[126]    AnyKindTest    ::=    "node" "(" ")"
[127]    DocumentTest    ::=    "document-node" "(" (ElementTest | SchemaElementTest)? ")"
[128]    TextTest    ::=    "text" "(" ")"
[129]    CommentTest    ::=    "comment" "(" ")"
[130]    PITest    ::=    "processing-instruction" "(" (NCName | StringLiteral)? ")"
[131]    AttributeTest    ::=    "attribute" "(" (AttribNameOrWildcard ("," TypeName)?)? ")"
[132]    AttribNameOrWildcard    ::=    AttributeName | "*"
[133]    SchemaAttributeTest    ::=    "schema-attribute" "(" AttributeDeclaration ")"
[134]    AttributeDeclaration    ::=    AttributeName
[135]    ElementTest    ::=    "element" "(" (ElementNameOrWildcard ("," TypeName "?"?)?)? ")"
[136]    ElementNameOrWildcard    ::=    ElementName | "*"
[137]    SchemaElementTest    ::=    "schema-element" "(" ElementDeclaration ")"
[138]    ElementDeclaration    ::=    ElementName
[139]    AttributeName    ::=    QName
[140]    ElementName    ::=    QName
[141]    TypeName    ::=    QName
[142]    URILiteral    ::=    StringLiteral
[143]    RevalidationDecl    ::=    "declare" "revalidation" ("strict" | "lax" | "skip")
[144]    InsertExprTargetChoice    ::=    (("as" ("first" | "last"))? "into")
| "after"
| "before"
[145]    InsertExpr    ::=    "insert" ("node" | "nodes") SourceExpr InsertExprTargetChoice TargetExpr
[146]    DeleteExpr    ::=    "delete" ("node" | "nodes") TargetExpr
[147]    ReplaceExpr    ::=    "replace" ("value" "of")? "node" TargetExpr "with" ExprSingle
[148]    RenameExpr    ::=    "rename" "node" TargetExpr "as" NewNameExpr
[149]    SourceExpr    ::=    ExprSingle
[150]    TargetExpr    ::=    ExprSingle
[151]    NewNameExpr    ::=    ExprSingle
[152]    TransformExpr    ::=    "copy" "$" VarName ":=" ExprSingle ("," "$" VarName ":=" ExprSingle)* "modify" ExprSingle "return" ExprSingle
[153]    BlockExpr    ::=    "block" Block
[154]    Block    ::=    "{" BlockDecls BlockBody "}"
[155]    BlockDecls    ::=    (BlockVarDecl ";")*
[156]    BlockVarDecl    ::=    "declare" "$" VarName TypeDeclaration? (":=" ExprSingle)? ("," "$" VarName TypeDeclaration? (":=" ExprSingle)?)*
[157]    BlockBody    ::=    Expr
[158]    AssignmentExpr    ::=    "$" VarName ":=" ExprSingle
[159]    ExitExpr    ::=    "exit" "returning" ExprSingle
[160]    WhileExpr    ::=    "while" "(" ExprSingle ")" WhileBody
[161]    WhileBody    ::=    Block

A.1 Terminal Symbols

[162]    IntegerLiteral    ::=    Digits
[163]    DecimalLiteral    ::=    ("." Digits) | (Digits "." [0-9]*) /* ws: explicitXQ */
[164]    DoubleLiteral    ::=    (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits /* ws: explicitXQ */
[165]    StringLiteral    ::=    ('"' (PredefinedEntityRef | CharRef | EscapeQuot | [^"&])* '"') | ("'" (PredefinedEntityRef | CharRef | EscapeApos | [^'&])* "'") /* ws: explicitXQ */
[166]    PredefinedEntityRef    ::=    "&" ("lt" | "gt" | "amp" | "quot" | "apos") ";" /* ws: explicitXQ */
[167]    EscapeQuot    ::=    '""'
[168]    EscapeApos    ::=    "''"
[169]    ElementContentChar    ::=    Char - [{}<&]
[170]    QuotAttrContentChar    ::=    Char - ["{}<&]
[171]    AposAttrContentChar    ::=    Char - ['{}<&]
[172]    Comment    ::=    "(:" (CommentContents | Comment)* ":)" /* ws: explicitXQ */
/* gn: commentsXQ */
[173]    PITarget    ::=    [http://www.w3.org/TR/REC-xml#NT-PITarget]XML /* gn: xml-versionXQ */
[174]    CharRef    ::=    [http://www.w3.org/TR/REC-xml#NT-CharRef]XML /* gn: xml-versionXQ */
[175]    QName    ::=    [http://www.w3.org/TR/REC-xml-names/#NT-QName]Names /* gn: xml-versionXQ */
[176]    NCName    ::=    [http://www.w3.org/TR/REC-xml-names/#NT-NCName]Names /* gn: xml-versionXQ */
[177]    S    ::=    [http://www.w3.org/TR/REC-xml#NT-S]XML /* gn: xml-versionXQ */
[178]    Char    ::=    [http://www.w3.org/TR/REC-xml#NT-Char]XML /* gn: xml-versionXQ */

The following symbols are used only in the definition of terminal symbols; they are not terminal symbols in the grammar of [A EBNF for XQuery 1.0 Grammar with Scripting Extensions].

[179]    Digits    ::=    [0-9]+
[180]    CommentContents    ::=    (Char+ - (Char* ('(:' | ':)') Char*))

A.2 Extra-grammatical Constraints

This section contains XQuery SX specific constraints on the EBNF productions, which are required to parse legal sentences. The notes below are referenced from the right side of the production, with the notation: /* gn: <id> */.

Constraint: sx-reserved-function-names

XQuery SX adds the term "while" to the list of names in Section A.3 Reserved Function NamesXQ.

Note:

This is a backwards incompatibility with [XQuery 1.0].

B XML Syntax (XQueryX) for XQuery Scripting Extension 1.0

[XML Syntax for XQuery 1.0] defines an XML representation of [XQuery 1.0]. [XQuery Scripting Requirements] states "The syntax for updates MAY have more than one syntax binding. One syntax MUST be convenient for humans to read and write. One syntax MUST be expressed in XML in a way that reflects the underlying structure of the operations." This appendix specifies an XML Schema that defines the XML representation of XQuery Scripting Extension 1.0 by representing the abstract syntax found in [A EBNF for XQuery 1.0 Grammar with Scripting Extensions]. This XML representation for XQuery Scripting Extension 1.0 integrates with the XML representation for XQuery 1.0 and that for the XQuery Update Facility 1.0.

The XML Schema specified in this appendix accomplishes its integration by importing the XML Schema defined for XQueryX in [XQuery Update Facility], incorporating all of its type and element definitions. It then extends that schema by adding definitions of new types and elements in a namespace belonging to the XQuery Scripting Extension 1.0 specification.

B.1 Schema

This section specifies the XML Schema that defines the complex types and elements for XQueryX in support of XQuery Scripting Extension 1.0, including changes to the prolog and the addition of several new expressions. It also specifies a second XML Schema that redefines an element defined in XQueryX 1.0. Copies of these two schemata can be found at http://www.w3.org/2008/xquery-sx-10/xquery-sx-10-xqueryx.xsd. and http://www.w3.org/2008/xquery-sx-10/xquery-sx-10-xqueryx-redef.xsd. Please note that the content of these schemata are subject to change at any time before this document is published as a Recommendation.


<xsd:schema
     xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     xmlns:xqx="http://www.w3.org/2005/XQueryX"
     xmlns:xqxuf="http://www.w3.org/2007/xquery-update-10"
     xmlns:xqxsx="http://www.w3.org/2008/xquery-sx-10"
     targetNamespace="http://www.w3.org/2008/xquery-sx-10"
     elementFormDefault="qualified" 
     attributeFormDefault="unqualified">

<!-- Initial creation                  2008-03-01: Jim Melton -->
<!-- Added FunctionDecl redefinition   2008-03-11: Jim Melton -->
<!-- Updated to new WD grammar         2008-11-25: Jim Melton -->
<!-- Reviewed, cleaned, corrections    2009-08-17: Jim Melton -->
<!-- Updated to recent grammar changes 2010-02-15: Jim Melton -->
  <xsd:import namespace="http://www.w3.org/2005/XQueryX"
     schemaLocation="http://www.w3.org/2008/xquery-sx-10/xquery-sx-10-xqueryx-redef.xsd"/>

  <!-- Declare new type for constant declarations             -->
  <!-- Corresponds to the following grammar productions:      -->
  <!-- VarDecl ::= "declare" ([un]assignable variable)        -->
  <!--               "$" QName TypeDeclaration?               -->
  <!--               ((":=" ExprSingle) | "external")         -->
  <xsd:complexType name="constDecl">
    <xsd:sequence>
      <xsd:element name="constName" type="xqx:QName"/>
      <xsd:element ref="typeDeclaration" minOccurs="0"/>
      <xsd:choice>
        <xsd:element name="varValue" type="exprWrapper"/>
        <xsd:element name="external" type="emptyContent"/>
      </xsd:choice>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:element name="constDecl" type="xqxsx:constDecl"
               substitutionGroup="xqx:prologPartTwoItem"/>


  <!-- Create substitution grp for scripting extension exprs  -->
  <xsd:complexType name="expr">
    <xsd:complexContent>
      <xsd:extension base="xqx:expr"/>
    </xsd:complexContent>
  </xsd:complexType>

  <!-- Make scripting extension subst grp part of expr grp    -->
  <xsd:element name="expr" type="xqxsx:expr" abstract="true"
               substitutionGroup="xqx:expr"/>


  <!-- AssignmentExpr:                                        -->
  <!--   AssignmentExpr ::= "$" VarName ":=" ExprSingle       -->
  <xsd:complexType name="assignmentExpr">
    <xsd:complexContent>
      <xsd:extension base="xqxsx:expr">
        <xsd:sequence>
          <xsd:element ref="xqx:positionalVariableBinding"/>
          <xsd:element name="assignedExpr" type="xqx:exprWrapper"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="assignmentExpr" type="xqxsx:assignmentExpr"
               substitutionGroup="xqxsx:expr"/>


  <!-- Block (1 of 3):                                        -->
  <!--   BlockExpr ::= "block" Block                          -->
  <!--   Block ::= "{" BlockDecls BlockBody "}"               -->
  <!--   BlockDecls ::= (BlockVarDecl ";")*                   -->
  <xsd:complexType name="block">
    <xsd:complexContent>
      <xsd:extension base="xqxsx:expr">
        <xsd:sequence>
          <xsd:element ref="xqxsx:blockVarDecl"
                       minOccurs="0" maxOccurs="unbounded"/>
          <xsd:element ref="xqxsx:blockBody"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="block" type="xqxsx:block"
               substitutionGroup="xqxsx:expr"/>

  <!-- Block (2 of 3):                                        -->
  <!--   BlockVarDecl ::=                                     -->
  <!--     "declare" "$" VarName TypeDeclaration?             -->
  <!--             (":=" ExprSingle)?                         -->
  <!--          ("," "$" VarName TypeDeclaration?             -->
  <!--             (":=" ExprSingle)? )*                      -->
  <xsd:complexType name="blockVarDecl">
      <xsd:sequence minOccurs="1" maxOccurs="unbounded">
        <xsd:element name="varName" type="xqx:QName"/>
        <xsd:element ref="xqx:typeDeclaration" minOccurs="0"/>
        <xsd:element name="varValue" type="xqx:exprWrapper"
                     minOccurs="0"/>
      </xsd:sequence>
  </xsd:complexType>

  <xsd:element name="blockVarDecl" type="xqxsx:blockVarDecl"/>

  <!-- Block (3 of 3):                                        -->
  <!--   BlockBody ::= Expr                                   -->
  <xsd:complexType name="blockBody">
    <xsd:sequence>
      <xsd:element name="blockExpr" type="xqx:exprWrapper"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:element name="blockBody" type="xqxsx:blockBody"/>


  <!-- ExitExpr:                                              -->
  <!--   ExitExpr ::= "exit" "returning" ExprSingle           -->
  <xsd:element name="exitExpr" type="xqxsx:expr"
               substitutionGroup="xqxsx:expr"/>


  <!-- WhileExpr:                                             -->
  <!--   WhileExpr ::= "while" "(" ExprSingle ")" WhileBody   -->
  <!--   WhileBody ::= Block                                  -->
  <xsd:complexType name="whileExpr">
    <xsd:complexContent>
      <xsd:extension base="xqxsx:expr">
        <xsd:sequence>
          <xsd:element name="whileTest" type="xqx:exprWrapper"/>
          <xsd:element ref="xqxsx:block"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="whileExpr" type="xqxsx:whileExpr"
               substitutionGroup="xqxsx:expr"/>


  <!-- ApplyExpr:                                             -->
  <!--   ApplyExpr ::= (ConcatExpr ";")+                      -->
  <xsd:complexType name="applyExpr">
    <xsd:complexContent>
      <xsd:extension base="xqxsx:expr">
        <xsd:sequence>
          <xsd:element name="applyExprs" maxOccurs="unbounded">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element ref="xqxsx:expr" maxOccurs="unbounded"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="applyExpr" type="xqxsx:applyExpr"
               substitutionGroup="xqxsx:expr"/>

</xsd:schema>



<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                    xmlns="http://www.w3.org/2005/XQueryX"
                    targetNamespace="http://www.w3.org/2005/XQueryX"
                    elementFormDefault="qualified" attributeFormDefault="qualified">

<!-- Redefine one or more components of the XQueryX XML Schema -->
<!-- The redefinition starts with XQuery Update Facility 1.0   -->
<!--   XQueryX instead of XQueryX 1.0                          -->
<xsd:redefine schemaLocation="http://www.w3.org/2007/xquery-update-10/xquery-update-10-xqueryx-redef.xsd">

<!-- Redefine the functionDecl complex type -->
  <xsd:complexType name="functionDecl">
    <xsd:complexContent>
      <xsd:extension base="functionDecl">
        <xsd:attribute name="simpleFunction"
                       type="xsd:boolean" default="true"/>
        <xsd:attribute name="sequentialFunction"
                       type="xsd:boolean" default="false"/>
        <xsd:attribute name="sequentialFunction"
                       type="xsd:boolean" default="false"/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

</xsd:redefine>

</xsd:schema>

B.2 Stylesheet

This section specifies the XSLT stylesheet that defines the semantics of XQueryX in support of XQuery Scripting Extension 1.0. It imports the XSLT stylesheet defined in [XQuery Update Facility], and provides additional templates that define the semantics of the XQueryX representation of XQuery Scripting Extension 1.0 by transforming that XQueryX representation into the human readable syntax of XQuery Scripting Extension 1.0. A copy of this stylesheet is located at http://www.w3.org/2008/xquery-sx-10/xquery-sx-10-xqueryx.xsl. Please note that the content of this stylesheet is subject to change at any time before this document is published as a Recommendation.


<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xqx="http://www.w3.org/2005/XQueryX"
                xmlns:xqxuf="http://www.w3.org/2007/xquery-update-10"
                xmlns:xqxsx="http://www.w3.org/2008/xquery-sx-10">

<!-- Initial creation                  2008-03-01: Jim Melton -->
<!-- Reviewed, cleaned, corrections    2009-08-17: Jim Melton -->
<!-- Updated to recent grammar changes 2010-02-15: Jim Melton -->

<xsl:import href="http://www.w3.org/2007/xquery-update-10/xquery-update-10-xqueryx.xsl"/>


<!-- constDecl                                                -->
<!-- 2010-02-15: "constant" is now "unassignable variable"    -->
<xsl:template match="xqxsx:constDecl">
  <xsl:value-of select="$NEWLINE"/>
  <xsl:text>declare unassignable variable </xsl:text>
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="xqxsx:constName">
  <xsl:apply-templates/>
</xsl:template>


<!-- Over-ride the template for varDecl in XQueryX.xsd        -->
<!-- 2010-02-15: "variable" is now "assignable variable"      -->
  <xsl:template match="xqx:varDecl" priority="200">
    <xsl:text>declare assignable variable </xsl:text>
    <xsl:value-of select="$DOLLAR"/>
    <xsl:apply-templates select="xqx:varName"/>
    <xsl:apply-templates select="xqx:typeDeclaration"/>
    <xsl:if test="xqx:external">
      <xsl:text> external </xsl:text>
    </xsl:if>
    <xsl:if test="xqx:varValue">
      <xsl:value-of select="$ASSIGN"/>
      <xsl:apply-templates select="xqx:varValue"/>
    </xsl:if>
  </xsl:template>


<!-- assignmentExpr                                           -->
<!-- 2010-02-15: Remove 'set' keyword                         -->
<xsl:template match="xqxsx:assignmentExpr">
  <xsl:value-of select="$NEWLINE"/>
  <xsl:apply-templates select="xqx:positionalVariableBinding"/>
  <xsl:text> := </xsl:text>
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="xqxsx:assignedExpr">
  <xsl:apply-templates/>
</xsl:template>


<!-- block                                                    -->
<!-- 2010-02-15: Added 'block' keyword                        -->
<xsl:template match="xqxsx:block">
  <xsl:value-of select="$NEWLINE"/>
  <xsl:text>block </xsl:text>
  <xsl:value-of select="$LBRACE"/>
  <xsl:value-of select="$SPACE"/>
  <xsl:apply-templates/>
  <xsl:value-of select="$SPACE"/>
  <xsl:value-of select="$RBRACE"/>
  <xsl:value-of select="$SPACE"/>
</xsl:template>

<!-- blockVarDecl                                             -->
<xsl:template match="xqxsx:blockVarDecl[position()=1 and position()=last()]">
  <xsl:text>declare </xsl:text>
  <xsl:apply-templates select="xqxsx:varName"/>
  <xsl:if test="xqx:typeDeclaration">
    <xsl:apply-templates select="xqx:typeDeclaration"/>
  </xsl:if>
  <xsl:if test="xqxsx:varValue">
    <xsl:text> := </xsl:text>
    <xsl:apply-templates select="xqxsx:varValue"/>
  </xsl:if>
  <xsl:value-of select="$SEMICOLON"/>
</xsl:template>

<xsl:template match="xqxsx:blockVarDecl[position()=1 and position()!=last()]">
  <xsl:text>declare </xsl:text>
  <xsl:apply-templates select="xqxsx:varName"/>
  <xsl:if test="xqx:typeDeclaration">
    <xsl:apply-templates select="xqx:typeDeclaration"/>
  </xsl:if>
  <xsl:if test="xqxsx:varValue">
    <xsl:text> := </xsl:text>
    <xsl:apply-templates select="xqxsx:varValue"/>
  </xsl:if>
</xsl:template>

<xsl:template match="xqxsx:blockVarDecl[position()>1 and position()&lt;last()]">
  <xsl:value-of select="$COMMA"/>
  <xsl:value-of select="$NEWLINE"/>
  <xsl:apply-templates select="xqxsx:varName"/>
  <xsl:if test="xqx:typeDeclaration">
    <xsl:apply-templates select="xqx:typeDeclaration"/>
  </xsl:if>
  <xsl:if test="xqxsx:varValue">
    <xsl:text> := </xsl:text>
    <xsl:apply-templates select="xqxsx:varValue"/>
  </xsl:if>
</xsl:template>

<xsl:template match="xqxsx:blockVarDecl[position()>1 and position()=last()]">
  <xsl:value-of select="$COMMA"/>
  <xsl:value-of select="$NEWLINE"/>
  <xsl:apply-templates select="xqxsx:varName"/>
  <xsl:if test="xqx:typeDeclaration">
    <xsl:apply-templates select="xqx:typeDeclaration"/>
  </xsl:if>
  <xsl:if test="xqxsx:varValue">
    <xsl:text> := </xsl:text>
    <xsl:apply-templates select="xqxsx:varValue"/>
  </xsl:if>
  <xsl:value-of select="$SEMICOLON"/>
</xsl:template>

<xsl:template match="xqxsx:varName">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="xqxsx:varValue">
  <xsl:apply-templates/>
</xsl:template>

<!-- blockBody                                                -->
<xsl:template match="xqxsx:blockBody">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="xqxsx:blockExpr">
  <xsl:apply-templates/>
</xsl:template>


<!-- exitExpr                                          -->
<xsl:template match="xqxsx:exitExpr">
  <xsl:value-of select="$NEWLINE"/>
  <xsl:text>exit returning </xsl:text>
  <xsl:apply-templates/>
</xsl:template>


<!-- whileExpr                                                -->
<xsl:template match="xqxsx:whileExpr">
  <xsl:value-of select="$NEWLINE"/>
  <xsl:text>while </xsl:text>
  <xsl:value-of select="$LPAREN"/>
  <xsl:value-of select="$SPACE"/>
  <xsl:apply-templates select="xqxsx:whileTest"/>
  <xsl:value-of select="$SPACE"/>
  <xsl:value-of select="$RPAREN"/>
  <xsl:value-of select="$NEWLINE"/>
  <xsl:apply-templates select="xqxsx:block"/>
  <xsl:value-of select="$NEWLINE"/>
</xsl:template>

<xsl:template match="xqxsx:whileTest">
  <xsl:apply-templates/>
</xsl:template>


<!-- applyExpr                                                -->
<xsl:template match="xqxsx:applyExpr">
  <xsl:value-of select="$NEWLINE"/>
  <xsl:apply-templates select="xqxsx:applyExprs"/>
  <xsl:value-of select="$NEWLINE"/>
</xsl:template>

<xsl:template match="xqxsx:applyExprs">
  <xsl:apply-templates/>
  <xsl:value-of select="$SEMICOLON"/>
</xsl:template>


<!-- Over-ride the template for functionDecl in XQuery        -->
<!--   Update Facility xquery-update-10-xqueryx-redef.xsd     -->
  <xsl:template match="xqx:functionDecl" priority="200">
    <xsl:text>declare </xsl:text>
    <xsl:choose>
      <xsl:when test="@xqx:updatingFunction and
                      @xqx:updatingFunction = 'true'">
        <xsl:text>updating </xsl:text>
      </xsl:when>
      <xsl:when test="@xqx:sequentialFunction and
                      @xqx:sequentialFunction = 'true'">
        <xsl:text>sequential </xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>simple </xsl:text>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:text>function </xsl:text>
    <xsl:apply-templates select="xqx:functionName"/>
    <xsl:apply-templates select="xqx:paramList"/>
    <xsl:apply-templates select="xqx:typeDeclaration"/>
    <xsl:apply-templates select="xqx:functionBody"/>
    <xsl:if test="xqx:externalDefinition">
      <xsl:text> external </xsl:text>
    </xsl:if>
  </xsl:template>



</xsl:stylesheet>

B.3 Example

The following example is based on the data and queries in the use cases in [XQuery Scripting Use Cases]. In this example, we show the English description of the query, the XQuery Scripting Extension solution given in [XQuery Scripting Use Cases], an XQueryX solution, and the XQuery Update Facility expression that results from applying the Update Facility XQueryX-to-XQuery Update Facility transformation defined by the stylesheet in [B.2 Stylesheet] to the Scripting Extension XQueryX solution. The XQuery Scripting Extension expression that is produced is presented only as a sanity-check—the intent of the stylesheet is not to recreate the original XQuery expression, but to produce a valid XQuery expression with the same semantics. The semantics of the Scripting Extension XQueryX solution are determined by the semantics of the XQuery Update Facility expression that results from that transformation. The "correctness" of that transformation is determined by asking the following the question: Can some Scripting Extension XQueryX processor QX process some Scripting Extension XQueryX document D1 to produce results R1, after which the stylesheet is used to translate D1 into an XQuery Scripting Extension expression E1 that, when processed by some XQuery Scripting Extension processor Q, produces results R2 that are equivalent (under some meaningful definition of "equivalent") to results R1?

Comparison of the results of the Scripting Extension XQueryX-to-XQuery Scripting Extension transformation given in this document with the XQuery Scripting Extension solutions in [XQuery Scripting Use Cases] may be helpful in evaluating the correctness of the Update Facility XQueryX solution in each example.

The XQuery Scripting Extension Use Cases solution given for each example is provided only to assist readers of this document in understanding the Scripting Extension XQueryX solution. There is no intent to imply that this document specifies a "compilation" or "transformation" of XQuery Scripting Extension syntax into Scripting Extension XQueryX syntax.

In the following example, note that path expressions are expanded to show their structure. Also, note that the prefix syntax for binary operators like "and" makes the precedence explicit. In general, humans find it easier to read an XML representation that does not expand path expressions, but it is less convenient for programmatic representation and manipulation. XQueryX is designed as a language that is convenient for production and modification by software, and not as a convenient syntax for humans to read and write.

Finally, please note that white space, including new lines, have been added to some of the Scripting Extension XQueryX documents and XQuery Scripting Extension expressions for readability. That additional white space is not produced by the Scripting Extension XQueryX-to-XQuery Scripting Extension transformation.

This example is based on query "Q2" from [XQuery Scripting Use Cases], use case "R": "Scripting Relational Data":

B.3.1 XQuery Representation

let $uid := doc("users.xml")/users/user_tuple[name = "Roger Smith"]/userid
let $topbid := max(doc("bids.xml")/bids/bid_tuple[itemno = 1007]/bid)
let $newbid := $topbid * 1.1
return
  if($newbid <= 240) then {
    insert nodes
      <bid_tuple>
        <userid>{ data($uid) }</userid>
        <itemno>1002</itemno>
        <bid>{ $newbid }</bid>
        <bid_date>1999-03-03</bid_date>
      </bid_tuple>
    into doc("bids.xml")/bids;
    exit returning <new_bid>{ $newbid }</new_bid>;
  } else {
    exit returning <top_bid>{ $topbid }</top_bid>;
  }

B.3.2 XQueryX Representation

<?xml version="1.0"?>
<!--
let $uid := doc("users.xml")/users/user_tuple[name = "Roger Smith"]/userid
let $topbid := max(doc("bids.xml")/bids/bid_tuple[itemno = 1007]/bid)
let $newbid := $topbid * 1.1
return
  if($newbid <= 240) then {
    insert nodes
      <bid_tuple>
        <userid>{ data($uid) }</userid>
        <itemno>1002</itemno>
        <bid>{ $newbid }</bid>
        <bid_date>1999-03-03</bid_date>
      </bid_tuple>
    into doc("bids.xml")/bids;
    exit returning <new_bid>{ $newbid }</new_bid>;
  } else {
    exit returning <top_bid>{ $topbid }</top_bid>;
  }
-->
<xqx:module xmlns:xqx="http://www.w3.org/2005/XQueryX"
            xmlns:xqxuf="http://www.w3.org/2007/xquery-update-10"
            xmlns:xqxsx="http://www.w3.org/2008/xquery-sx-10"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.w3.org/2005/XQueryX
                                http://www.w3.org/2005/XQueryX/xqueryx.xsd
                                http://www.w3.org/2007/xquery-update-10                            
http://www.w3.org/2007/xquery-update-10/xquery-update-10-xqueryx.xsd
                                http://www.w3.org/2008/xquery-sx-10                            
http://www.w3.org/2008/xquery-sx-10/xquery-sx-10-xqueryx.xsd">

    <xqx:queryBody>
      <xqx:flworExpr>
<!-- let $uid := doc("users.xml")/users/user_tuple[name = "Roger Smith"]/userid -->
        <xqx:letClause>
          <xqx:letClauseItem>
            <xqx:typedVariableBinding>
              <xqx:varName>uid</xqx:varName>
            </xqx:typedVariableBinding>
            <xqx:letExpr>
              <xqx:pathExpr>
                <xqx:stepExpr>
                  <xqx:filterExpr>
                    <xqx:functionCallExpr>
                      <xqx:functionName
                        xqx:prefix="fn">doc</xqx:functionName>
                      <xqx:arguments>
                        <xqx:stringConstantExpr>
                          <xqx:value>users.xml</xqx:value>
                        </xqx:stringConstantExpr>
                      </xqx:arguments>
                    </xqx:functionCallExpr>
                  </xqx:filterExpr>
                </xqx:stepExpr>
                <xqx:stepExpr>
                  <xqx:xpathAxis>child</xqx:xpathAxis>
                  <xqx:nameTest>users</xqx:nameTest>
                </xqx:stepExpr>
                <xqx:stepExpr>
                  <xqx:xpathAxis>child</xqx:xpathAxis>
                  <xqx:nameTest>user-tuple</xqx:nameTest>
                  <xqx:predicates>
                    <xqx:equalOp>
                      <xqx:firstOperand>
                        <xqx:pathExpr>
                          <xqx:stepExpr>
                            <xqx:xpathAxis>child</xqx:xpathAxis>
                            <xqx:nameTest>name</xqx:nameTest>
                          </xqx:stepExpr>
                        </xqx:pathExpr>
                      </xqx:firstOperand>
                      <xqx:secondOperand>
                        <xqx:stringConstantExpr>
                          <xqx:value>Roger Smith</xqx:value>
                        </xqx:stringConstantExpr>
                      </xqx:secondOperand>
                    </xqx:equalOp>
                  </xqx:predicates>
                </xqx:stepExpr>
                <xqx:stepExpr>
                  <xqx:xpathAxis>child</xqx:xpathAxis>
                  <xqx:nameTest>userid</xqx:nameTest>
                </xqx:stepExpr>
              </xqx:pathExpr>
            </xqx:letExpr>
          </xqx:letClauseItem>
        </xqx:letClause>
<!-- let $topbid := max(doc("bids.xml")/bids/bid_tuple[itemno = 1007]/bid) -->
        <xqx:letClause>
          <xqx:letClauseItem>
            <xqx:typedVariableBinding>
              <xqx:varName>topbid</xqx:varName>
            </xqx:typedVariableBinding>
            <xqx:letExpr>
              <xqx:pathExpr>
                <xqx:stepExpr>
                  <xqx:filterExpr>
                    <xqx:functionCallExpr>
                      <xqx:functionName
                        xqx:prefix="fn">max</xqx:functionName>
                      <xqx:arguments>
                        <xqx:pathExpr>
                          <xqx:stepExpr>
                            <xqx:filterExpr>
                              <xqx:functionCallExpr>
                                <xqx:functionName
                                  xqx:prefix="fn">doc</xqx:functionName>
                                <xqx:arguments>
                                  <xqx:stringConstantExpr>
                                    <xqx:value>bids.xml</xqx:value>
                                  </xqx:stringConstantExpr>
                                </xqx:arguments>
                              </xqx:functionCallExpr>
                            </xqx:filterExpr>
                          </xqx:stepExpr>
                          <xqx:stepExpr>
                            <xqx:xpathAxis>child</xqx:xpathAxis>
                            <xqx:nameTest>bids</xqx:nameTest>
                          </xqx:stepExpr>
                          <xqx:stepExpr>
                            <xqx:xpathAxis>child</xqx:xpathAxis>
                            <xqx:nameTest>bid-tuple</xqx:nameTest>
                            <xqx:predicates>
                              <xqx:equalOp>
                                <xqx:firstOperand>
                                  <xqx:pathExpr>
                                    <xqx:stepExpr>
                                      <xqx:xpathAxis>child</xqx:xpathAxis>
                                      <xqx:nameTest>itemno</xqx:nameTest>
                                    </xqx:stepExpr>
                                  </xqx:pathExpr>
                                </xqx:firstOperand>
                                <xqx:secondOperand>
                                  <xqx:integerConstantExpr>
                                    <xqx:value>1007</xqx:value>
                                  </xqx:integerConstantExpr>
                                </xqx:secondOperand>
                              </xqx:equalOp>
                            </xqx:predicates>
                          </xqx:stepExpr>
                          <xqx:stepExpr>
                            <xqx:xpathAxis>child</xqx:xpathAxis>
                            <xqx:nameTest>bid</xqx:nameTest>
                          </xqx:stepExpr>
                        </xqx:pathExpr>
                      </xqx:arguments>
                    </xqx:functionCallExpr>
                  </xqx:filterExpr>
                </xqx:stepExpr>
              </xqx:pathExpr>
            </xqx:letExpr>
          </xqx:letClauseItem>
        </xqx:letClause>
<!-- let $newbid := $topbid * 1.1 -->
        <xqx:letClause>
          <xqx:letClauseItem>
            <xqx:typedVariableBinding>
              <xqx:varName>newbid</xqx:varName>
            </xqx:typedVariableBinding>
            <xqx:letExpr>
              <xqx:multiplyOp>
                <xqx:firstOperand>
                  <xqx:varRef>
                    <xqx:name>topbid</xqx:name>
                  </xqx:varRef>
                </xqx:firstOperand>
                <xqx:secondOperand>
                  <xqx:decimalConstantExpr>
                    <xqx:value>1.1</xqx:value>
                  </xqx:decimalConstantExpr>
                </xqx:secondOperand>
              </xqx:multiplyOp>
            </xqx:letExpr>
          </xqx:letClauseItem>
        </xqx:letClause>
<!-- return -->
        <xqx:returnClause>
<!--   if($newbid <= 240)        -->
          <xqx:ifThenElseExpr>
            <xqx:ifClause>
              <xqx:lessThanOrEqualOp>
                <xqx:firstOperand>
                  <xqx:varRef>
                    <xqx:name>newbid</xqx:name>
                  </xqx:varRef>
                </xqx:firstOperand>
                <xqx:secondOperand>
                  <xqx:integerConstantExpr>
                    <xqx:value>240</xqx:value>
                  </xqx:integerConstantExpr>
                </xqx:secondOperand>
              </xqx:lessThanOrEqualOp>
            </xqx:ifClause>
<!--                      then { -->
            <xqx:thenClause>
              <xqxsx:block>
                <xqxsx:blockBody>
                  <xqxsx:blockExpr>
<!--     insert nodes -->
                    <xqxuf:insertExpr>
                      <xqxuf:sourceExpr>
<!--       <bid_tuple> -->
                        <xqx:elementConstructor>
                          <xqx:tagName>bid_tuple</xqx:tagName>
                          <xqx:elementContent>
<!--         <userid>{ data($uid) }</userid> -->
                            <xqx:elementConstructor>
                              <xqx:tagName>userid</xqx:tagName>
                              <xqx:elementContent>
                                <xqx:functionCallExpr>
                                  <xqx:functionName
                                    xqx:prefix="fn">data</xqx:functionName>
                                  <xqx:arguments>
                                    <xqx:exprList>
                                      <xqx:expr>
                                        <xqx:varRef>
                                          <xqx:name>uid</xqx:name>
                                        </xqx:varRef>
                                      </xqx:expr>
                                    </xqx:exprList>
                                  </xqx:arguments>
                                </xqx:functionCallExpr>
                              </xqx:elementContent>
                            </xqx:elementConstructor>
<!--         <itemno>1002</itemno> -->
                            <xqx:elementConstructor>
                              <xqx:tagName>itemno</xqx:tagName>
                              <xqx:elementContent>
                                <xqx:integerConstantExpr>
                                  <xqx:value>1002</xqx:value>
                                </xqx:integerConstantExpr>
                              </xqx:elementContent>
                            </xqx:elementConstructor>
<!--         <bid>{ $newbid }</bid> -->
                            <xqx:elementConstructor>
                              <xqx:tagName>bid</xqx:tagName>
                              <xqx:elementContent>
                                <xqx:varRef>
                                  <xqx:name>bid</xqx:name>
                                </xqx:varRef>
                              </xqx:elementContent>
                            </xqx:elementConstructor>
<!--         <bid_date>1999-03-03</bid_date> -->
                            <xqx:elementConstructor>
                              <xqx:tagName>bid_date</xqx:tagName>
                              <xqx:elementContent>
                                <xqx:stringConstantExpr>
                                  <xqx:value>1999-03-03</xqx:value>
                                </xqx:stringConstantExpr>
                              </xqx:elementContent>
                            </xqx:elementConstructor>
                          </xqx:elementContent>
                        </xqx:elementConstructor>
                      </xqxuf:sourceExpr>
<!--     into doc("bids.xml")/bids; -->
                      <xqxuf:insertInto/>
                      <xqxuf:targetExpr>
                        <xqx:pathExpr>
                          <xqx:stepExpr>
                            <xqx:filterExpr>
                              <xqx:functionCallExpr>
                                <xqx:functionName
                                  xqx:prefix="fn">doc</xqx:functionName>
                                <xqx:arguments>
                                  <xqx:stringConstantExpr>
                                    <xqx:value>bids.xml</xqx:value>
                                  </xqx:stringConstantExpr>
                                </xqx:arguments>
                              </xqx:functionCallExpr>
                            </xqx:filterExpr>
                          </xqx:stepExpr>
                          <xqx:stepExpr>
                            <xqx:xpathAxis>child</xqx:xpathAxis>
                            <xqx:nameTest>bids</xqx:nameTest>
                          </xqx:stepExpr>
                        </xqx:pathExpr>
                      </xqxuf:targetExpr>
                    </xqxuf:insertExpr>
                  </xqxsx:blockExpr>
<!--     exit returning <new_bid>{ $newbid }</new_bid>; -->
                  <xqxsx:blockExpr>
                    <xqxsx:exitExpr>
                      <xqx:elementConstructor>
                        <xqx:tagName>new_bid</xqx:tagName>
                        <xqx:elementContent>
                          <xqx:varRef>
                            <xqx:name>newbid</xqx:name>
                          </xqx:varRef>
                        </xqx:elementContent>
                      </xqx:elementConstructor>
                    </xqxsx:exitExpr>
                  </xqxsx:blockExpr>
                </xqxsx:blockBody>
              </xqxsx:block>
            </xqx:thenClause>
<!--   } else { -->
            <xqx:elseClause>
<!--     exit returning <top_bid>{ $topbid }</top_bid>; -->
              <xqxsx:block>
                <xqxsx:blockBody>
                  <xqxsx:blockExpr>
                    <xqxsx:exitExpr>
                      <xqx:elementConstructor>
                        <xqx:tagName>top_bid</xqx:tagName>
                        <xqx:elementContent>
                          <xqx:varRef>
                            <xqx:name>topbid</xqx:name>
                          </xqx:varRef>
                        </xqx:elementContent>
                      </xqx:elementConstructor>
                    </xqxsx:exitExpr>
                  </xqxsx:blockExpr>
                </xqxsx:blockBody>
              </xqxsx:block>
            </xqx:elseClause>
          </xqx:ifThenElseExpr>
        </xqx:returnClause>
<!-- } -->
      </xqx:flworExpr>
    </xqx:queryBody>
</xqx:module>

B.3.3 Transformed XQuery Representation

Application of the stylesheet in [B.2 Stylesheet] to the Update Facility XQueryX representation results in the following XQuery representation:

( let $uid:=fn:doc("users.xml")/child::users/
        child::user-tuple[(child::name = "Roger Smith")]/
        child::userid
  let $topbid:=fn:max(fn:doc("bids.xml")/
        child::bids/child::bid-tuple[(child::itemno = 1007)]/
        child::bid)
  let $newbid:=($topbid*1.1)
  return
    ( if (($newbid <= 240)) then {
        insert nodes 
          <bid_tuple>
            <userid>{fn:data($uid)}</userid>
            <itemno>{1002}</itemno>
            <bid>{$bid}</bid>
            <bid_date>{"1999-03-03"}</bid_date>
          </bid_tuple>
        into 
          fn:doc("bids.xml")/child::bids
        exit returning <new_bid>{$newbid}</new_bid> }
      else { 
        exit returning <top_bid>{$topbid}</top_bid> } )
)

C Implementation-Defined Items

The following items in this specification are implementation-defined:

  1. The effects of snapshot semantics on persistent storage. For example, it is implementation-defined whether the effects of an fn:put function are visible to an fn:doc, fn:doc-available, or fn:collection function executed in a subsequent snapshot.

  2. The mechanism (if any) by which the XQuery environment exchanges parameters and results with an external function.

D References

XQuery 1.0
XQuery 1.0: An XML Query Language, W3C Recommendation, 23 January 2007.
XML Syntax for XQuery 1.0
XML Syntax for XQuery 1.0, W3C Recommendation, 23 January 2007.
XQuery Data Model
XQuery 1.0 and XPath 2.0 Data Model (XDM), W3C Recommendation, 23 January 2007.
XQuery 1.0 and XPath 2.0 Functions and Operators
XQuery 1.0 and XPath 2.0 Functions and Operators, W3C Recommendation, 23 January 2007.
XQuery Update Facility
XQuery Update Facility 1.0, W3C Candidate Recommendation, March 2008.
XQuery Scripting Requirements
XQuery Scripting Extension 1.0 Requirements, W3C Working Draft, 23 March 2007.
XQuery Scripting Use Cases
XQuery Scripting Extension 1.0 Use Cases, W3C Working Draft 23 March 2007.
XQuery 1.1
XQuery 1.1: An XML Query Language, W3C Working Draft, 15 December 2009.

E Error Conditions

E.1 New Error Codes

err:SXST0002

It is a static error to mix both updating and sequential operands in an expression.

err:SXDY0003

It is a dynamic error if, after applying a pending update list (using upd:applyUpdates), the XDM instance bound to any in-scope variable does not match the static type of that variable according to SequenceType matching rules.

err:SXDY0004

It is an dynamic error for an external sequential function to return a non-empty pending update list.

err:SXST0005

It is a static error if two or more variables declared in the same block expression have the same expanded QName.

err:SXTY0006

A reference to a variable, other than on the left-hand side of an assignment expression, is an error if the variable has no value in variable values when the reference is evaluated.

err:SXST0007

The variable on the left-hand side of an assignment must have been declared in one of the following ways:

  • By a block variable declaration

  • As a parameter to a sequential function

  • By a variable declaration in the Prolog declared as assignable

err:SXST0008

It is a static error if the body of a function violates the category rules for it's declared category.

err:SXST0009

A static error is raised if the value for a xqsx:query-mode option or pragma is not either sequential or simple.

E.2 Amendments to Existing Error Codes

err:XUST0001

It is a static error for an updating or sequential expression to occur in the following places:

  1. As the initializing expression of a prolog variable.

  2. As a StepExpr in a RelativePathExpr when query mode is simple.

  3. As the primary expression or a predicate expression of a FilterExpr or AxisStep when query mode is simple.

  4. In the for, let, where, or order by clauses of a FLWOR expression when query mode is simple.

  5. In a quantified expression clause or as the satisfies expression of a quantified expression when query mode is simple.

F Glossary (Non-Normative)

XDM instance

An XDM instance is an unconstrained sequence of zero or more nodes and/or atomic values, as defined in [XQuery Data Model].

XQSX

XQSX is an abbreviation for XQuery Scripting Extension.

XQUF

XQUF is an abbreviation for [XQuery Update Facility].

apply expression

An apply expression is a list of semicolon-terminated ConcatExpr productions, called operand expressions. An ApplyExpr consisting of a single ConcatExpr with no semicolon is not an apply expression.

assignable

Prolog variables declared as assignable may have their value changed by an [5.3 Assignment Expression].

constant

XQSX allows the keyword constant to be used in place of variable in a Prolog declaration. A variable declared in this way is called a constant.

evaluation order

XQSX defines an evaluation order on many kinds of XQuery expressions, which is the order that operand expressions must be evaluated in order to determine what side-effects are visible to later expressions.

initializing expression

The expression on the right-hand side of a block variable declaration is called an initializing expression.

pending update list

A pending update list is an unordered collection of update primitives, representing node state changes that have not yet been applied, as defined in [XQuery Update Facility].

query mode

The query mode governs the composability of updating and sequential expressions. Valid values are sequential and simple.

sequential expression

A sequential expression is an expression that can have side effects other than constructing a new node or raising an error.

sequential function

A sequential function is a function whose declaration specifies the keyword sequential.

simple expression

A simple expression is an expression that is neither an updating expression nor a sequential expression.

simple function

A simple function is a function whose declaration specifies neither updating nor sequential. A simple function may optionally specify the keyword simple.

snapshot

A snapshot is a scope within which expressions are evaluated with respect to a fixed XDM instance and updates are held pending.

test expression

The expression enclosed in the parentheses of a while expression is called a test expression.

updating expression

An updating expression is an expression that can return a non-empty pending update list.

updating function

An updating function is a function whose declaration specifies the keyword updating.

G Revision Log (Non-Normative)

This log records the substantive changes that have been made to this document. Minor editorial changes are not included in this log.

This document was built from files checked in on $Date: 2010/04/05 22:10:44 $.

G.1 Since the 3 December 2008 Working Draft

  • Changed "exit with" to "exit returning"

  • Relaxed restrictions on where sequential expressions can occur.

  • The type of a block variable is never inferred from it's initializing expression.

  • Removed the "set" keyword from an assignment expression.

  • Changed "variable"/"constant" to "unassignable variable" and "assignable variable".

  • Made execution scope and snapshot scope analogous, so stable functions can change value in subsequent snapshots.

  • Added query mode to the static context, along with an option and pragma to change it.

  • Added error codes for all error conditions.

G.2 Since the 28 March 2008 Working Draft

  • Relaxed the restrictions on where updating expressions can occur to a superset of those allowed by [XQuery Update Facility].

  • Re-check the SequenceType of bound variables after upd:applyUpdates is invoked.

  • Added the "block" keyword to the grammer for block expressions.

  • Removed the break and continue expressions.

  • Added the semi-colon (apply) expression to apply updates, removing the semi-colon separated list from block expressions.

  • Added the ability to set the value of parameters to sequential functions.