Copyright © 2010 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
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.
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.
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
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
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:
It is a strict superset of XQUF, in the sense that all valid XQUF expressions are also valid XQSX expressions and have the same meaning. (In the same sense, XQUF is a strict superset of [XQuery 1.0].)
It does not introduce any "modes" that affect the semantics of expressions.
As in XQUF, the result of an expression consists of an XDM instance and a pending update list. [Definition: An XDM instance is an unconstrained sequence of zero or more nodes and/or atomic values, as defined in [XQuery Data Model].] [Definition: 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].]
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.
[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.
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
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.
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:
An updating expression is allowed anywhere a simple expression is allowed. If an operand of an expression is an updating expression, the expression itself is an updating expression.
An expression may not be both sequential and updating. If an updating expression contains or uses a sequential expression (or vice versa), an error is raised [err:SXST0002].
The pending update
list that results from any given expression is the result of
calling upd:mergeUpdates
on the pending update lists from
the result of all of its operand expressions. No pending update list is
ever discarded.
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].
[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.
[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.
[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 |
XQSX adds the pair
(xqsx
,
http://www.w3.org/2008/xquery-sx-10
) as a predefined
namespace to the statically known namespaces.
[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].
[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].
[26] | FunctionDecl |
::= | ("declare" ("simple"? | "updating") "function" QName "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external")) |
[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
.]
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.
If the body of a function violates the category rules for it's declared category, [err:SXST0008] is raised.
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:
A return type is permitted.
If external
is specified, the external function may
return both a non-empty pending update list and a non-empty XDM instance.
If the result of an updating 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 an updating function is
item()*
.
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].
[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
.
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 |
[32] | ApplyExpr |
::= | ConcatExpr (";"
(ConcatExpr
";")*)? |
[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.
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.
[153] | BlockExpr |
::= | "block" Block |
[154] | Block |
::= | "{" BlockDecls
BlockBody "}" |
[155] | BlockDecls |
::= | (BlockVarDecl
";")* |
[156] | BlockVarDecl |
::= | "declare" "$" VarName
TypeDeclaration? (":="
ExprSingle)? ("," "$"
VarName TypeDeclaration? (":=" ExprSingle)?)* |
[157] | BlockBody |
::= | Expr |
[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.
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.
[158] | AssignmentExpr |
::= | "$" VarName ":="
ExprSingle |
An assignment expression is a sequential expression.
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.
[160] | WhileExpr |
::= | "while" "(" ExprSingle ")" WhileBody |
[161] | WhileBody |
::= | Block |
[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.
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.
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; }
[159] | ExitExpr |
::= | "exit" "returning" ExprSingle |
The operand of an exit expression may be an expression of any category.
An exit expression is a sequential expression.
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.
[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
.
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.
[91] | ParenthesizedExpr |
::= | "(" Expr? ")" |
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.
[95] | FunctionCall |
::= | QName "(" (ExprSingle ("," ExprSingle)*)? ")" |
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.
Argument expressions are evaluated from left to right, then the function is invoked.
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
.
[70] | PathExpr |
::= | ("/" RelativePathExpr?) |
[71] | RelativePathExpr |
::= | StepExpr (("/" |
"//") StepExpr)* |
The category of a path expression is determined by the following rules:
If query mode is
simple
, [err:XUST0001] is raised if any StepExpr in the
RelativePathExpr is an updating or sequential
expression.
If any StepExpr in the RelativePathExpr is an updating expression, then all StepExpr must be updating or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the path expression is an updating expression.
If any StepExpr in the RelativePathExpr is a sequential expression, then all StepExpr must be sequential or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the path expression is a sequential expression.
Otherwise, the path expression is a simple expression.
StepExpr are evaluated in order from left to right.
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.
[73] | AxisStep |
::= | (ReverseStep |
ForwardStep) PredicateList |
[83] | FilterExpr |
::= | PrimaryExpr
PredicateList |
[84] | PredicateList |
::= | Predicate* |
[85] | Predicate |
::= | "[" Expr "]" |
The category of a FilterExpr or AxisStep is determined by the following rules:
If query mode is
simple
, [err:XUST0001] is raised if the primary
expression or a predicate expression of any FilterExpr or AxisStep
is an updating or sequential
expression.
If either the primary expression or any predicate expression of a FilterExpr or AxisStep is an updating expression, then all such expressions must be updating or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the FilterExpr or AxisStep is an updating expression.
If either the primary expression or any predicate expression of a FilterExpr or AxisStep is a sequential expression, then all such expressions must be sequential or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the FilterExpr or AxisStep is a sequential expression.
Otherwise, the FilterExpr or AxisStep is a simple expression.
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.
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.
[33] | ConcatExpr |
::= | ExprSingle (","
ExprSingle)* |
The category of a concatenation expression is determined by the following rules:
If any operand is an updating expression, then all operands must be updating or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the concatenation expression is an updating expression.
If any operand is a sequential expression, then all operands must be sequential or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the concatenation expression is a sequential expression.
Otherwise, the concatenation expression is a simple expression.
Operand expressions are evaluated once, from left to right. Side effects of each sequential operand expression are visible to subsequent operand expressions.
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.
[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
"}" |
The category of a node constructor is determined by the following rules:
If any operand is an updating expression, then all operands must be updating or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the node constructor is an updating expression.
If any operand is a sequential expression, then all operands must be sequential or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the node constructor is a sequential expression.
Otherwise, the node constructor is a simple expression.
The name expression is evaluated (computed element/attribute/processing-instruction constructors only).
The direct attribute constructors are evaluated from left to right (direct element constructors only).
The child or value expressions are evaluated from left to right.
The pending update
lists from each operand expression are concatenated by the
upd:mergeUpdates
operation, producing the resulting
pending update list.
[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)? |
The for
, let
, where
, and
order by
clauses can either be all simple
and updating expressions, or all simple and sequential
expressions.
If query mode is
simple
, [err:XUST0001] is raised if any for
,
let
, where
, or order by
clause is an updating or sequential
expression.
If the above clauses contain an updating expression, then all clauses must either be a simple expression or an updating expression, otherwise a static error is raised [err:SXST0002]. The FLWOR expression itself is an updating expression.
If the above clauses contain a sequential expression, then all clauses must either be a simple expression or an sequential expression, otherwise a static error is raised [err:SXST0002]. The FLWOR expression itself is an sequential expression.
If the above clauses do not contain an updating
expression or a sequential expression, then the
return
clause may be an expression of any category.
The category of the FLWOR expression is the same as the category of
the expression in its return
clause.
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.
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.
[47] | IfExpr |
::= | "if" "(" Expr ")" "then"
ExprSingle "else" ExprSingle |
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.
If the test, then or else expression is an updating expression, the conditional expression is an updating expression.
If the test, then or else expression is a sequential expression, the conditional expression is a sequential expression.
Otherise, the conditional expression is a simple expression.
The test expression is evaluated first. Next either the then expression or the else expression (but not both) is evaluated.
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
.
[44] | QuantifiedExpr |
::= | ("some" | "every") "$" VarName TypeDeclaration? "in" ExprSingle ("," "$" VarName TypeDeclaration? "in" ExprSingle)* "satisfies" ExprSingle |
The category of a quantified expression is determined by the following rules:
If query mode is
simple
, [err:XUST0001] is raised if any quantified
expression clause or the satisfies expression is an updating or
sequential expression.
If any quantified expression clause or the satisfies expression is an updating expression, then all such expressions must be updating or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the quantified expression is an updating expression.
If any quantified expression clause or the satisfies expression is a sequential expression, then all such expressions must be sequential or simple expressions, otherwise a static error is raised [err:SXST0002]. In this case, the quantified expression is a sequential expression.
Otherwise, the quantified expression is a simple expression.
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.
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
.
[45] | TypeswitchExpr |
::= | "typeswitch" "(" Expr ")"
CaseClause+ "default" ("$"
VarName)? "return" ExprSingle |
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.
If an operand, case or default expression is an updating expression, the typeswitch expression is an updating expression.
If an operand, case or default expression is a sequential expression, the typeswitch expression is a sequential expression.
Otherise, the typeswitch expression is a simple expression.
The operand expression is evaluated first. Then, exactly one of the return expressions is evaluated.
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
.
[145] | InsertExpr |
::= | "insert" ("node" | "nodes") SourceExpr InsertExprTargetChoice
TargetExpr |
[144] | InsertExprTargetChoice |
::= | (("as" ("first" | "last"))? "into") |
[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 |
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.
Order of evaluation for insert, delete, replace, and rename expressions is irrelevent since their operands cannot be sequential expressions.
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
.
[152] | TransformExpr |
::= | "copy" "$" VarName
":=" ExprSingle ("," "$"
VarName ":=" ExprSingle)* "modify" ExprSingle "return" ExprSingle |
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.
If one of the copy or return clauses is an updating expression, the transform expression is an updating expression.
If one of the copy, modify or return clauses is a sequential expression, the transform expression is a sequential expression.
Otherise, the transform expression is a simple expression.
Copy clauses are evaluated in order, then the modify expression is evaluated. Finally the return clause is evaluated.
The semantics of a transform expression as defined in Section 2.4.5 TransformXU are extended as follows:
If the modify clause returns a non-empty XDM instance it is discarded.
The pending update
list returned by the transform expression is calculated by
merging the pending
update lists from the copy clause and the return clause using
upd:mergeUpdates
.
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)
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.
Operand expressions are evaluated once, from left to right.
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
.
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; }
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")) |
|
[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 |
|
[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 |
|
[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?) |
/* 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" "::") |
|
[76] | AbbrevForwardStep |
::= | "@"? NodeTest |
|
[77] | ReverseStep |
::= | (ReverseAxis
NodeTest) | AbbrevReverseStep |
|
[78] | ReverseAxis |
::= | ("parent" "::") |
|
[79] | AbbrevReverseStep |
::= | ".." |
|
[80] | NodeTest |
::= | KindTest | NameTest |
|
[81] | NameTest |
::= | QName | Wildcard |
|
[82] | Wildcard |
::= | "*" |
/* 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 |
|
[97] | DirectConstructor |
::= | DirElemConstructor |
|
[98] | DirElemConstructor |
::= | "<" QName DirAttributeList ("/>" |
(">" DirElemContent*
"</" QName S? ">")) |
/* ws: explicitXQ */ |
[99] | DirAttributeList |
::= | (S (QName S? "="
S? DirAttributeValue)?)* |
/* ws: explicitXQ */ |
[100] | DirAttributeValue |
::= | ('"' (EscapeQuot |
QuotAttrValueContent)*
'"') |
/* ws: explicitXQ */ |
[101] | QuotAttrValueContent |
::= | QuotAttrContentChar |
|
[102] | AposAttrValueContent |
::= | AposAttrContentChar |
|
[103] | DirElemContent |
::= | DirectConstructor |
|
[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 |
|
[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" "(" ")") |
|
[122] | OccurrenceIndicator |
::= | "?" | "*" | "+" |
/* gn: occurrence-indicatorsXQ */ |
[123] | ItemType |
::= | KindTest | ("item"
"(" ")") | AtomicType |
|
[124] | AtomicType |
::= | QName |
|
[125] | KindTest |
::= | DocumentTest |
|
[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") |
|
[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 |
[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*)) |
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].
[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.
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>
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()<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>
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":
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>; }
<?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>
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> } ) )
The following items in this specification are implementation-defined:
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.
The mechanism (if any) by which the XQuery environment exchanges parameters and results with an external function.
It is a static error to mix both updating and sequential operands in an expression.
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.
It is an dynamic error for an external sequential function to return a non-empty pending update list.
It is a static error if two or more variables declared in the same block expression have the same expanded QName.
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.
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
It is a static error if the body of a function violates the category rules for it's declared category.
A static error is raised if the value for a
xqsx:query-mode
option or pragma is not either
sequential
or simple
.
It is a static error for an updating or sequential expression to occur in the following places:
As the initializing expression of a prolog variable.
As a StepExpr in a RelativePathExpr when query mode is simple
.
As the primary expression or a predicate expression of a
FilterExpr or AxisStep when query mode is simple
.
In the for
, let
, where
,
or order by
clauses of a FLWOR expression when
query mode is
simple
.
In a quantified expression clause or as the satisfies expression
of a quantified expression when query mode is simple
.
An XDM instance is an unconstrained sequence of zero or more nodes and/or atomic values, as defined in [XQuery Data Model].
XQSX is an abbreviation for XQuery Scripting Extension.
XQUF is an abbreviation for [XQuery Update Facility].
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.
Prolog variables declared as assignable may have their value changed by an [5.3 Assignment Expression].
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.
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.
The expression on the right-hand side of a block variable declaration is called an initializing expression.
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].
The query mode governs the composability of updating and
sequential expressions. Valid values are
sequential
and simple
.
A sequential expression is an expression that can have side effects other than constructing a new node or raising an error.
A sequential function is a function whose declaration
specifies the keyword sequential
.
A simple expression is an expression that is neither an updating expression nor a sequential expression.
A simple function is a function whose declaration
specifies neither updating
nor
sequential
. A simple function may optionally specify
the keyword simple
.
A snapshot is a scope within which expressions are evaluated with respect to a fixed XDM instance and updates are held pending.
The expression enclosed in the parentheses of a while expression is called a test expression.
An updating expression is an expression that can return a non-empty pending update list.
An updating function is a function whose declaration
specifies the keyword updating
.
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 $.
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.
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.