W3C

XQuery Scripting Extension 1.0

W3C Working Draft 3 December 2008

This version:
http://www.w3.org/TR/2008/WD-xquery-sx-10-20081203
Latest version:
http://www.w3.org/TR/xquery-sx-10/
Previous version:
http://www.w3.org/TR/2008/WD-xquery-sx-10-20080328/
Editors:
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>
Jerome Simeon, IBM T.J. Watson Research Center <simeon@us.ibm.com>
John Snelson, Oracle Corporation <john.snelson@oracle.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 the concept of a block with local variable declarations, as well as several new kinds of expressions, including assignment, while, and exit expressions.

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.

Since its initial publication as a First Public Working Draft, a number of changes have been made to this specification. Among those changes are: the removal of the break and continue expressions, a revision of the syntax that makes semicolons into operators that apply pending update lists, a change in the syntax of blocks to avoid double curly braces, and the correction of some examples.

The most significant change is that the restrictions on where updating expressions can be used in an XQuery expression and where they are not permitted was relaxed. More information about this can be found in [E Issues].

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 28 March 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 XQuery 1.0
    2.1 Extensions to the Processing Model
        2.1.1 Evaluation Order
        2.1.2 Snapshot Scope
        2.1.3 Variable Binding Revalidation
    2.2 Extensions to the Prolog
        2.2.1 Constants and Variables
        2.2.2 Function Declarations
    2.3 New Kinds of Expressions
        2.3.1 Apply Expression
        2.3.2 Block Expressions
        2.3.3 Assignment Expression
        2.3.4 Exit Expression
        2.3.5 While Expression
    2.4 Changes to Existing Expressions
        2.4.1 Function Calls
        2.4.2 FLWOR Expressions
        2.4.3 Conditional Expressions
        2.4.4 Typeswitch Expressions
        2.4.5 Comma Expressions
        2.4.6 Parentheses
        2.4.7 Ordered and Unordered Expressions
        2.4.8 Transform Expressions
        2.4.9 Extension Expressions
        2.4.10 Insert, Delete, Replace, and Rename Expressions
        2.4.11 Other Expressions
3 Example

Appendices

A EBNF for XQuery 1.0 Grammar with Scripting Extensions
    A.1 Terminal Symbols
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 Issues
F Glossary (Non-Normative)
G Revision Log (Non-Normative)
    G.1 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: XQSE is an abbreviation for XQuery Scripting Extension.]

XQSE has the following properties:

The principal extensions introduced by XQSE are as follows:

  1. An ordering is defined on the evaluation of certain kinds of XQuery expressions. An implementation may use any execution strategy as long as the result complies with the semantics of this ordering. The ordering is defined in a way that places no additional constraints on the evaluation of any valid XQUF or [XQuery 1.0] expressions.

  2. Expressions in XQSE may have side-effects that are visible to subsequent expressions (according to the above ordering of evaluation).

  3. XQSE introduces the following new kinds of expressions:

    1. Apply (semicolon) expressions

    2. Blocks

    3. Assignment expressions

    4. Exit expressions

    5. While expressions

  4. XQSE 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.

  5. XQSE 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 [2.3 New Kinds of Expressions] and [2.4 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, XQSE 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

2 Extensions to XQuery 1.0

2.1 Extensions to the Processing Model

2.1.1 Evaluation Order

XQSE defines an ordering on the evaluation of certain kinds of XQuery expressions. An implementation may use any execution strategy as long as the result complies with the semantics of this ordering. Since some of the expressions introduced by XQSE have immediate side effects, a well-defined evaluation order is necessary for a deterministic result.

XQSE semantics are defined by the following evaluation order:

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

Function calls: Argument expressions are evaluated before the function body.

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

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

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

Block: Variable declarations are evaluated first, in the order written; then the expression in the body is evaluated.

While: The test expression is evaluated first. If its effective Boolean value is false, the body is not evaluated. If the effective Boolean value of the test expression is true, the body is evaluated repeatedly until the value of the test expression becomes false. Side effects of each iteration are visible to subsequent iterations.

Note:

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

2.1.2 Snapshot 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, XQSE permits a query to contain more than one snapshot. In XQSE, each of the following expressions is a snapshot:

  • 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

Like [XQuery Update Facility], this specification defines the semantics of operations on an XDM instance. Propagation of changes to an underlying persistent store (if any) is beyond the scope of this specification. Thus, 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.1.3 Variable Binding Revalidation

To ensure type soundness, variable bindings are revalidated at the end of each scope to ensure that any updates applied have not made them invalid with repect to their declared types. It is a dynamic error [err:TBD] 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.2 Extensions to the Prolog

2.2.1 Constants and Variables

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

[Definition: XQSE 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.]

Rules for initializing variables and for determining the scope of variables apply equally to constants. The semantics of constants are the same as the semantics of variables, with the following exception: It is a static error [err:TBD] if a constant appears on the left-hand-side of an assignment expression.

The initializing expression in a variable or constant declaration in a Prolog must be a simple expression [err:TBD].

2.2.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:

If the body of a simple function is an EnclosedExpr, it must be a simple expression.

If the body of an updating function is an EnclosedExpr, it must be either an updating or simple expression.

If the body of a sequential function is a Block it must be either a sequential or simple expression.

Semantics:

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

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 [2.3.4 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]. 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:TBD].

2.3 New Kinds of Expressions

XQSE 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 | ConcatExpr
[32]    ApplyExpr    ::=    (ConcatExpr ";")+
[33]    ConcatExpr    ::=    ExprSingle ("," ExprSingle)*
[34]    ExprSingle    ::=    FLWORExpr
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| InsertExpr
| DeleteExpr
| RenameExpr
| ReplaceExpr
| TransformExpr
| BlockExpr
| AssignmentExpr
| ExitExpr
| WhileExpr
| OrExpr

2.3.1 Apply Expression

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

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

An apply expression is a sequential expression.

Semantics:

An apply expression consists of one or more semicolon-terminated operand expressions. The operand expressions 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.

2.3.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.

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:TBD] 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 inferred from the type of its initializing expression. If the variable has neither an explicit type declaration nor an initializing expression, its type 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:TBD].

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:TBD].

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.

2.3.3 Assignment Expression

[158]    AssignmentExpr    ::=    "set" "$" 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 three ways:

  • By a block variable declaration

  • As a parameter to a sequential function

  • By a variable declaration in the Prolog

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

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:TBD]. 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.

2.3.4 Exit Expression

[159]    ExitExpr    ::=    "exit" "with" 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.

2.3.5 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.

The WhileBody can be an expression of any category.

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) { 
     set $fibseq := ($fibseq, $c);
     set $a := $b;
     set $b := $c;
     set $c := $a + $b;
  };

  $fibseq;
}

2.4 Changes to Existing Expressions

XQSE introduces the new expression category of sequential expressions, as well as relaxing the constraints on updating expressions. The category rules and semantic changes for existing [XQuery 1.0] and [XQuery Update Facility] expressions follow certain principles:

2.4.1 Function Calls

Category Rules:

If the function called is a simple function, the argument expressions must be simple expressions or updating expressions. If the argument expressions contain an updating expression then the function call is an updating 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. The function call expression is a sequential expression.

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.

2.4.2 FLWOR Expressions

Category Rules:

The for, let, where, and order by clauses must contain either simple expressions or updating expressions.

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.

2.4.3 Conditional Expressions

Category Rules:

The test expression must be a simple expression or an updating expression.

Let the then and else expressions be called branches. Then:

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.

2.4.4 Typeswitch Expressions

Category Rules:

The expression in the operand expression must be a simple expression or an updating expression.

Let the expressions in the case and default clauses be called branches. Then:

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.

2.4.5 Comma Expressions

Category Rules:

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

Semantics:

The comma 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.

2.4.6 Parentheses

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.

2.4.7 Ordered and Unordered Expressions

Category Rules:

The operand of an ordered or unordered expression may be an expression of any category. The category of the ordered or unordered expression is the same as the category of its operand.

2.4.8 Transform Expressions

Category Rules:

The modify clause must contain an updating or simple expression.

The copy clause must contain a simple expression or an updating expression.

Semantics:

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

2.4.9 Extension Expressions

Category Rules:

The operand of an extension expression may be an expression of any category. The category of the extension expression is the same as the category of its operand.

2.4.10 Insert, Delete, Replace, and Rename Expressions

Category Rules:

Insert, delete, replace, and rename expressions are updating expressions, and are extended to accept both updating and simple expressions as their operands.

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.

2.4.11 Other Expressions

Category Rules:

All expressions not listed above are extended to accept both updating and simple expressions as their operands. If an operand of the expression is updating then the expression itself is updating, otherwise it is simple.

This includes the following kinds of expressions:

  • Path expressions

  • Filter expressions

  • Range expressions

  • Union, intersect, and except expressions

  • Arithmetic, comparison, and logical expressions

  • Constructors of all kinds

  • Quantified expressions

  • Instance of, cast, castable, and treat expressions

  • Validate expressions

3 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";
           set $result := true();
        ) else (
           replace value of node $entry/access-allowed with "No";
           set $result := false();
        );
        insert node $entry as last into $log; 
        fn:put($log, "log.xml"); 
        exit with $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" ("variable" | "constant") "$" 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 | ConcatExpr
[32]    ApplyExpr    ::=    (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)? "#)"
[69]    PragmaContents    ::=    (Char* - (Char* '#)' Char*))
[70]    PathExpr    ::=    ("/" RelativePathExpr?)
| ("//" RelativePathExpr)
| RelativePathExpr
[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)
[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)*)? ")"
[96]    Constructor    ::=    DirectConstructor
| ComputedConstructor
[97]    DirectConstructor    ::=    DirElemConstructor
| DirCommentConstructor
| DirPIConstructor
[98]    DirElemConstructor    ::=    "<" QName DirAttributeList ("/>" | (">" DirElemContent* "</" QName S? ">"))
[99]    DirAttributeList    ::=    (S (QName S? "=" S? DirAttributeValue)?)*
[100]    DirAttributeValue    ::=    ('"' (EscapeQuot | QuotAttrValueContent)* '"')
| ("'" (EscapeApos | AposAttrValueContent)* "'")
[101]    QuotAttrValueContent    ::=    QuotAttrContentChar
| CommonContent
[102]    AposAttrValueContent    ::=    AposAttrContentChar
| CommonContent
[103]    DirElemContent    ::=    DirectConstructor
| CDataSection
| CommonContent
| ElementContentChar
[104]    CommonContent    ::=    PredefinedEntityRef | CharRef | "{{" | "}}" | EnclosedExpr
[105]    DirCommentConstructor    ::=    "<!--" DirCommentContents "-->"
[106]    DirCommentContents    ::=    ((Char - '-') | ('-' (Char - '-')))*
[107]    DirPIConstructor    ::=    "<?" PITarget (S DirPIContents)? "?>"
[108]    DirPIContents    ::=    (Char* - (Char* '?>' Char*))
[109]    CDataSection    ::=    "<![CDATA[" CDataSectionContents "]]>"
[110]    CDataSectionContents    ::=    (Char* - (Char* ']]>' Char*))
[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    ::=    "?" | "*" | "+"
[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    ::=    "set" "$" VarName ":=" ExprSingle
[159]    ExitExpr    ::=    "exit" "with" ExprSingle
[160]    WhileExpr    ::=    "while" "(" ExprSingle ")" WhileBody
[161]    WhileBody    ::=    Block

A.1 Terminal Symbols

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

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*))

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 -->
  <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" (... | "constant")               -->
  <!--               "$" 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:sequence>
          <xsd:element name="external">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="varValue" type="exprWrapper" minOccurs="0"/>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
      </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 ::= "set" "$" 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" "with" ExprSingle      -->
  <xsd:element name="exitExpr" type="xqxsx:expr"
               substitutionGroup="xqxsx:expr"/>


  <!-- WhileExpr:                                             -->
  <!--   WhileExpr ::= "while" "(" ExprSingle ")" 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 -->

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


<!-- constDecl                                                -->
<xsl:template match="xqxsx:constDecl">
  <xsl:value-of select="$NEWLINE"/>
  <xsl:text>declare constant </xsl:text>
  <xsl:apply-templates/>
</xsl:template>

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


<!-- assignmentExpr                                           -->
<xsl:template match="xqxsx:assignmentExpr">
  <xsl:value-of select="$NEWLINE"/>
  <xsl:text>set </xsl:text>
  <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                                                    -->
<xsl:template match="xqxsx:block">
  <xsl:value-of select="$NEWLINE"/>
  <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 with </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="$SEMICOLON"/>
</xsl:template>

<xsl:template match="xqxsx:applyExprs">
  <xsl:apply-templates/>
</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 with <new_bid>{ $newbid }</new_bid>;
  } else {
    exit with <top_bid>{ $topbid }</top_bid>;
  }

B.3.2 XQueryX 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 with <new_bid>{ $newbid }</new_bid>;
  } else {
    exit with <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 with <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:termSemicolon/>
                </xqxsx:blockBody>
              </xqxsx:block>
            </xqx:thenClause>
<!--   } else { -->
            <xqx:elseClause>
<!--     exit with <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:termSemicolon/>
                </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 with <new_bid>{$newbid}</new_bid>; }  else 
      { exit with <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 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.

E Issues

The following are some issues that are under discussion in the working group:

  1. Explicit declaration of simple functions:

    Some functions that contain sequential expressions nevertheless have no externally visible side effects. For example, if the Fibonacci block in [2.3.5 While Expression] were the body of a function, the function would have no externally visible side effects. Should it be possible for a user to declare such a function to be simple? Then it could be used (for example) in the for-clause of a FLWOR to iterate over Fibonacci numbers.

    The following issues have been discussed:

    1. We would need to trust the user's declaration, and an incorrect declaration might lead to unpredictable results.

    2. There are grammar problems because the body of a simple function is an enclosed expression, while the body of a sequential function is a block. These are not syntactically distinguishable with finite look-ahead, but they are not identical because an enclosed expression does not end with a semicolon. The following approaches to deal with this grammar problem have been considered:

      1. If a function is declared with no category, it takes an enclosed expression as its body and it is implicitly a simple function. If a function is explicitly declared "simple", it takes a block as its body (then its result is defined by an "exit" expression.)

      2. A simple function that contains a sequential expression must have double {{curly braces}} around its body: the outer { } denote an enclosed expression and the inner { } denote a block.

      3. Invent a new declaration like "programmed simple" to denote a simple function whose body is a block.

      4. Change the definition of a block so that, if its final expression has no semicolon, the value of that expression is returned as the value of the block. Then let the body of a simple function be a block instead of an enclosed expression. This approach leads to some new questions: What happens if the body of a while-loop returns a value? Should semicolons be allowed outside blocks? Do we still need an "exit" expression? Etc.

  2. Query modes to restrict the composability of updating and sequential expressions:

    The occurrence of updating or sequential sub-expressions in an expression can restrict the use of a number of well known and important optimizations. If these expressions are performance critical or handle large amounts of data (such as a database query), it may be useful to restrict or prohibit the use of such expressions. It may also be important to restrict updates in some queries for security reasons. The working group is considering adding query modes to allow the user to restrict the way that updating and sequential expressions can be used in queries.

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].

XQSE

XQSE is an abbreviation for XQuery Scripting Extension.

XQUF

XQUF is an abbreviation for [XQuery Update Facility].

constant

XQSE 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.

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].

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.

G.1 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.