Copyright © 2006 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This document defines an update facility that extends the XML Query language, XQuery. The XQuery Update Facility provides expressions that can be used to make persistent changes to instances of the XQuery 1.0 and XPath 2.0 Data Model.
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 document has been produced by the XML Query Working Group (part of the XML Activity), following the procedures set out in the W3C Process Document. This is the first version of this document. It is designed to be read in conjunction with the following documents:
This is the First Public Working Draft for review by W3C members and other interested parties. 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.
Public comments on this document and its open issues are invited. Comments on this document should be made in W3C's public Bugzilla system (instructions can be found at http://www.w3.org/XML/2005/04/qt-bugzilla). When entering comments, select the Product named "XPath / XQuery / XSLT", the Component named "Update Facility", and the Version named "Working drafts". If access to that system is not feasible, you may send your comments to the W3C XSLT/XPath/XQuery mailing list, public-qt-comments@w3.org. It will be very helpful if you include the string [UPD] in the subject line of your comment, whether made in Bugzilla or in email. Each Bugzilla entry and email message should contain only one comment. Archives of the comments and responses are available at http://lists.w3.org/Archives/Public/public-qt-comments/.
The patent policy for this document is specified in the 5 February 2004 W3C Patent Policy. Patent disclosures relevant to this specification may be found on the XML Query Working Group's patent disclosure page. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) with respect to this specification should disclose the information in accordance with section 6 of the W3C Patent Policy.
Per section 4 of the W3C Patent Policy, Working Group participants have 150 days from the title page date of this document to exclude essential claims from the W3C RF licensing requirements with respect to this document series. Exclusions are with respect to the exclusion reference document, defined by the W3C Patent Policy to be the latest version of a document in this series that is published no later than 90 days after the title page date of this document.
1 Introduction
2 Extensions to XQuery 1.0
2.1 Extensions to the Processing Model
2.2 Extensions to the Prolog
2.3 New Kinds of Expressions
2.3.1 Insert
2.3.2 Delete
2.3.3 Replace
2.3.4 Rename
2.3.5 Transform
2.4 Extensions to Existing Expressions
2.4.1 FLWOR Expression
2.4.2 Typeswitch Expression
2.4.3 Conditional Expression
2.4.4 Comma Expression
2.4.5 Parenthesized Expression
2.4.6 Function Declaration
2.4.7 Function Call
2.4.8 Other Expressions
3 Update Operations
3.1 upd:mergeUpdates
3.2 upd:revalidate
3.3 upd:applyUpdates
3.4 Update Primitives
3.4.1 upd:insertBefore
3.4.2 upd:insertAfter
3.4.3 upd:insertInto
3.4.4 upd:insertIntoAsLast
3.4.5 upd:insertAttributes
3.4.6 upd:delete
3.4.7 upd:replaceValue
3.4.8 upd:rename
3.5 Compatibility of Update Primitives
A EBNF for XQuery 1.0 Grammar with Update extensions
A.1 Terminal Symbols
B References
B.1 Normative References
B.2 Non-normative References
C Error Conditions
D Glossary (Non-Normative)
This document defines the syntax and semantics of an extension to [XQuery 1.0] called the XQuery Update Facility. This language extension is designed to meet the requirements for updating instances of the [XQuery/XPath Data Model (XDM)], as defined in [XQuery Update Facility Requirements].
The XQuery Update Facility provides facilities to perform any or all of the following operations on an XDM instance:
Insertion of a node.
Deletion of a node.
Modification of a node by changing some of its properties while preserving its identity.
Creation of a modified copy of a node with a new identity.
[Definition: Within this document, the term XQuery refers to the language specified by [XQuery 1.0].] [Definition: The term data model refers to the data model specified by [XQuery/XPath Data Model (XDM)].] [Definition: The term XDM instance denotes an unconstrained sequence of zero or more nodes and/or atomic values as defined by the data model.]
The basic building block of XQuery is the expression. XQuery 1.0 provides several kinds of expressions that can be composed with each other in arbitrary ways. An XQuery 1.0 expression takes one or more XDM instances as input and returns an XDM instance as a result. In XQuery 1.0, an expression never modifies the state of an existing node; however, constructor expressions create new nodes with new identities.
XQuery Update Facility classifies all XQuery expressions into the following mutually exclusive categories:
[Definition: An updating expression is an expression that can modify the state of an existing node.]
[Definition: A non-updating expression is an expression that cannot modify the state of an existing node.]
The extensions to XQuery 1.0 provided by XQuery Update Facility may be characterized as follows:
XQuery Update Facility introduces five new kinds of expressions, called insert, delete, replace, rename, and transform expressions. The first four of these are updating expressions, and the last (transform) is a non-updating expression. XQuery Update Facility specifies the syntax and semantics of each new kind of expression.
XQuery Update Facility defines how all the expressions of XQuery are classified as updating or non-updating expressions, and defines the places where each category of expression can be used. In so doing, it makes small extensions to the syntax and semantics of certain existing expressions.
XQuery Update Facility defines the following extensions to the XQuery processing model:
In XQuery 1.0, the result of each expression is an XDM instance. XQuery Update Facility extends the XQuery processing model so that the result of an expression consists of both an XDM instance and a pending update list (either or both of which may be empty). [Definition: A pending update list is an unordered collection of update primitives, which represent node state changes that have not yet been applied.]
XQuery Update Facility also defines a set of update operations. [Definition: Update operations are used in defining the semantics of XQuery updates, but are not directly available to users. Update operations are defined in 3 Update Operations.] Update operations consist of the following:
Update primitives are the components of pending update lists. [Definition: Each update primitive represents a node state change that has not yet been applied.] [Definition: The first argument of an update primitive, called its target node, is the principal node to be
affected by the update primitive.] Update primitives are held on pending update lists until they are made effective by a upd:applyUpdates
operation.
upd:mergeUpdates
is an update operation that operates on two pending update lists, merging them into a single pending update list.
upd:applyUpdates
is an update operation that makes the update primitives in a pending update list effective by applying them to an XDM instance.
upd:revalidate
is an update operation that applies schema validation to a node and its descendants, deriving new type annotations for these nodes while preserving their node identities.
If the outermost expression in a query returns a pending update list, upd:applyUpdates
is implicitly applied to this pending update list. If this invocation of upd:applyUpdates
signals an error condition, a dynamic error is raised [err:TBD].
Note:
[Definition: The upd:applyUpdates
operation determines the scope within which all expressions are evaluated before any updates are applied. This is sometimes called the scope of snapshot semantics.] XQuery Update Facility currently calls for upd:applyUpdates
to be applied only to the result of the topmost expression in a query, corresponding to query-level snapshot semantics. In
principle, upd:applyUpdates
could be invoked at a lower level, resulting in expression-level snapshot semantics. This change would require other semantic changes to ensure deterministic results. The Update Language Task Force is currently investigating the issue of snapshot semantics.
[7] | Setter |
::= | BoundarySpaceDecl | DefaultCollationDecl | BaseURIDecl | ConstructionDecl | OrderingModeDecl | EmptyOrderDecl | RevalidationDecl | CopyNamespacesDecl |
[141] | RevalidationDecl |
::= | "declare" "revalidation" ("strict" | "lax" | "skip") |
The Prolog is extended by adding a new kind of Setter called a revalidation declaration. [Definition: A revalidation declaration sets the revalidation mode in the static context, overriding any implementation-defined default.] If a Prolog contains more than one revalidation declaration, a static error is raised [err:TBD].
[Definition: Revalidation mode, which may be strict
, lax
, or skip
, is a component of the static context that controls the behavior of the upd:revalidate
operation.] The value of revalidation mode is determined as follows:
Default initial value: strict
.
Can be overwritten by an implementation: Yes.
Can be overwritten by a query: Yes, but a revalidation declaration may not specify a mode that is less strict than the implementation-defined default.
Scope: Global.
Consistency rules: Must be strict
, lax
, or skip
.
[32] | ExprSingle |
::= | FLWORExpr |
XQuery Update Facility extends the syntax of ExprSingle by adding five new kinds of expressions, called insert, delete, replace, rename, and transform expressions. The syntax and semantics of these expressions are described in the following sections.
[145] | InsertExpr |
::= | "insert" (DirectConstructor | ("{" SourceExpr "}")) ((("as" ("first" | "last"))? "into") |
[143] | SourceExpr |
::= | ExprSingle |
[142] | TargetExpr |
::= | ExprSingle |
[95] | DirectConstructor |
::= | DirElemConstructor |
An insert expression inserts copies of one or more nodes into a designated position in an XDM instance. If into
is specified without as first
or as last
, the position of the inserted nodes within their parent is implementation-dependent. An insert expression is an updating expression.
Examples:
Insert a year
element after the publisher of the first book.
insert <year>2005</year> after fn:doc("bib.xml")/books/book[1]/publisher
Navigating by means of several bound variables, insert a new police report into the list of police reports for a particular accident.
insert {$new-police-report} as last into fn:doc("insurance.xml")/policies /policy[id = $pid] /driver[license = $license] /accident[date = $accdate] /police-reports
The semantics of an insert expression are as follows:
If a DirectConstructor is specified, it is evaluated according to the rules in Section 3.7 of [XQuery 1.0]. The result is a single element, comment, or processing instruction node. Let $clist
be this node, and let $alist
be the empty sequence.
If a SourceExpr is specified, it must not be an updating expression; otherwise a static error is raised [err:XUST0101]. The SourceExpr is evaluated as though it were an enclosed expression in an element constructor (see Rule 1e in Section 3.7.1.3 of [XQuery 1.0]). The result of this step is either an error or a sequence of nodes to
be inserted, called the insertion sequence. If the insertion sequence contains a document node, the document node is replaced in the insertion sequence by its children. If the insertion sequence contains an attribute node following a node that is not an attribute node, a type error is raised [err:TBD]. Let $alist
be the sequence of attribute nodes in the insertion sequence. Let $clist
be the remainder of the insertion sequence, in its original order.
The target expression must not be an updating expression; otherwise a static error is raised [err:XUST0101]. The target expression is evaluated. If into
is specified, the result must be a single element node or a single document node; otherwise a type error is raised [err:TBD]. If before
or after
is specified, the result must be a single element node
whose parent
property is not empty; otherwise a dynamic error is raised [err:TBD]. Let $target
be the node returned by the target expression.
The result of the insert expression is a pending update list constructed as follows:
If as first
is specified and $target
has at least one child, let $child
be the first child node of $target
. The pending update list consists of the following update primitives:
If $alist
is not empty, upd:insertAttributes($target, $alist)
If $clist
is not empty, upd:insertBefore($child, $clist)
If as last
is specified, or as first
is specified and $target
has no children, the pending update list consists of the following update primitives:
If $alist
is not empty, upd:insertAttributes($target, $alist)
If $clist
is not empty, upd:insertIntoAsLast($target, $clist)
If into
is specified and neither as first
nor as last
is specified, the pending update list consists of the following update primitives:
If $alist
is not empty, upd:insertAttributes($target, $alist)
If $clist
is not empty, upd:insertInto($target, $clist)
If before
is specified, let $parent
be the parent node of $target
. The pending update list consists of the following update primitives:
If $alist
is not empty, upd:insertAttributes($parent, $alist)
If $clist
is not empty, upd:insertBefore($target, $clist)
If after
is specified, let $parent
be the parent node of $target
. The pending update list consists of the following update primitives:
If $alist
is not empty, upd:insertAttributes($parent, $alist)
If $clist
is not empty, upd:insertAfter($target, $clist)
[146] | DeleteExpr |
::= | "delete" "{" TargetExpr "}" |
[142] | TargetExpr |
::= | ExprSingle |
A delete expression deletes one or more nodes from an XDM instance. A delete expression is an updating expression.
Examples:
Delete the last author of the first book in a given bibliography.
delete {fn:doc("bib.xml")/books/book[1]/author[last()]}
Delete all email messages that are more than 365 days old.
delete {/email/message [fn:currentDate() - date > xdt:dayTimeDuration("P365D")]}
The semantics of a delete expression are as follows:
The target expression must not be an updating expression; otherwise a static error is raised [err:XUST0101]. The target expression is evaluated. The result must be a sequence of nodes; otherwise a type error is raised [err:TBD]. Let $tlist
be the list of nodes returned by the target expression.
A new pending update list is created. For each node $tnode
in $tlist
, the following update primitive is appended to the pending update list: upd:delete($tnode)
. The resulting pending update list is the result of the delete expression.
[147] | ReplaceExpr |
::= | "replace" ("value" "of")? "{" TargetExpr "}" "with" ExprSingle ("," "{" TargetExpr "}" "with" ExprSingle)* |
[142] | TargetExpr |
::= | ExprSingle |
A replace expression is an updating expression. A replace expression has two forms, depending on whether value of
is specified. In either case, a replace expression consists of one or more replacements, separated by commas. [Definition: A replacement is an
operation that replaces a node or modifies the value of a node.]
If value of
is not specified, each replacement replaces one node with a new sequence of zero or more nodes. Example:
Replace the publisher of the first book with the publisher of the second book.
replace {fn:doc("bib.xml")/books/book[1]/publisher} with fn:doc("bib.xml")/books/book[2]/publisher
The semantics of this form of replace expression are as follows:
The individual replacements can be processed in any order. Each replacement is processed as follows:
The expression following the keyword with
must not be an updating expression; otherwise a static error is raised [err:XUST0101]. This expression is evaluated as though it were an enclosed expression in an element constructor (see Rule 1e in Section 3.7.1.3 of [XQuery 1.0]). The result of this step is either an error or a sequence of nodes called the
replacement sequence. If the replacement sequence contains a document node, the document node is replaced in the replacement sequence by its children. If the replacement sequence contains an attribute node following a node that is not an attribute node, a type error is raised [err:TBD]. Let $alist
be the sequence of attribute nodes in the replacement sequence. Let $clist
be the remainder of the replacement sequence, in its original order.
The target expression must not be an updating expression; otherwise a static error is raised [err:XUST0101]. The target expression is evaluated. The result must be a single node whose parent
property is not empty; otherwise a dynamic error is raised [err:TBD]. Let $target
be the node returned by the target expression, and let $parent
be its parent
node.
Note:
$target
may not be a document node, since a document node does not have a parent property.
If $target
is an element, text, comment, or processing instruction node, the replacement generates a pending update list consisting of the following update primitives:
upd:insertAttributes($parent, $alist)
upd:insertBefore($target, $clist)
upd:delete($target)
If $target
is an attribute node, the replacement generates a pending update list consisting of the following update primitives:
upd:insertAttributes($parent, $alist)
upd:insertIntoAsLast($parent, $clist)
upd:delete($target)
The pending update lists generated by the individual replacements are merged by successive invocations of the upd:mergeUpdates
operation. If the upd:mergeUpdates
operation signals an incompatibility, a dynamic error is raised [err:TBD]. Otherwise, the result of the replace expression is the merged pending update list returned by the final upd:mergeUpdates
operation.
If value of
is specified, a replace expression is used to modify the value of a node while preserving its node identity. Example:
Increase the price of the first book by ten percent.
replace value of {fn:doc("bib.xml")/books/book[1]/price} with fn:doc("bib.xml")/books/book[1]/price * 1.1
The semantics of this form of replace expression are as follows:
The individual replacements can be processed in any order. Each replacement is processed as follows:
The expression following the keyword with
must not be an updating expression; otherwise a static error is raised [err:XUST0101]. This expression is evaluated as though it were the content expression of a text node constructor (see Section 3.7.3.4 of [XQuery 1.0].) The result of this step is either an error or a single text node. Let $text
be
the text node resulting from this step.
The target expression must not be an updating expression; otherwise a static error is raised [err:XUST0101]. The target expression is evaluated. The result must be a single node; otherwise a type error is raised [err:TBD]. Let $target
be the node returned by the target expression.
If $target
is an element node, let $clist
be a list of the children of $target
. The result of the replace expression is a pending update list consisting of the following update primitives:
For each node $cnode
in $clist
, upd:delete($cnode)
.
upd:insertIntoAsLast($target, $text)
If $target
is an attribute, text, comment, or processing instruction node, let $string
be the string value of the text node constructed in Step 1. The result of the replace expression is a pending update list containing the following update primitive: upd:replaceValue($target, $string)
.
If $target
is a document node, a type error is raised [err:TBD].
The pending update lists generated by the individual replacements are merged by successive invocations of the upd:mergeUpdates
operation. If the upd:mergeUpdates
operation signals an incompatibility, a dynamic error is raised [err:TBD]. Otherwise, the result of the replace expression is the merged pending update list returned by the final upd:mergeUpdates
operation.
[148] | RenameExpr |
::= | "rename" "{" TargetExpr "}" "to" NewNameExpr |
[142] | TargetExpr |
::= | ExprSingle |
[144] | NewNameExpr |
::= | ExprSingle |
A rename expression replaces the name
property of a data model node with a new QName. A rename expression is an updating expression.
Examples:
Rename the first author
element of the first book to principal-author
.
rename {fn:doc("bib.xml")/books/book[1]/author[1]} to "principal-author"
Rename the first author
element of the first book to the QName that is the value of the variable $newname
.
rename {fn:doc("bib.xml")/books/book[1]/author[1]} to $newname
The semantics of a rename expression are as follows:
The target expression must not be an updating expression; otherwise a static error is raised [err:XUST0101]. The target expression is evaluated. The result must be a single element, attribute, or processing instruction node; otherwise a type error is raised [err:TBD]. Let $target
be the node returned by the target expression.
NewNameExpr must not be an updating expression; otherwise a static error is raised [err:XUST0101]. NewNameExpr is evaluated as though it were the name expression of a computed element constructor (see Section 3.7.3.1 of [XQuery 1.0].) The result is either an error or an expanded QName. Let
$QName
be this expanded QName.
The result of the rename expression is a pending update list containing the following update primitive: upd:rename($target, $QName)
.
[149] | TransformExpr |
::= | "transform" "copy" "$" VarName ":=" ExprSingle ("," "$" VarName ":=" ExprSingle)* "do" ExprSingle "return" ExprSingle |
A transform expression can be used to create modified copies of existing nodes in an XDM instance. Each node created by a transform expression has a new node identity. The result of a transform expression is an XDM instance that may include both nodes that were created by the transform expression and other, previously existing nodes. A transform expression is a non-updating expression.
Example:
Return a sequence containing of all employee
elements that have Java as a skill, excluding their salary
child-elements:
for $e in //employee[skill = "Java"] return transform copy $je := $e do delete {$je/salary} return $je
A transform expression consists of three clauses, denoted by the keywords copy
, do
, and return
. The semantics of a transform expression are as follows:
The copy
clause contains one or more variable bindings, each of which consists of a variable name and an expression called the source expression. Each variable binding is processed as follows:
The source expression must not be an updating expression; otherwise a static error is raised [err:XUST0101]. The source expression is evaluated as though it were an enclosed expression in an element constructor (see Rule 1e in Section 3.7.1.3 of [XQuery 1.0].) The result of this step is either an error or a sequence of nodes called the copied node sequence.
Note:
Each node in the copied node sequence is a newly created node with a new nodeid.
The variable name is bound to the copied node sequence. The scope of this variable binding includes all subexpressions of the containing transform expression that appear after the variable binding clause, but it does not include the source expression to which the variable is bound.
The do
clause must contain either an updating expression, an empty expression ( )
, or a call to the fn:error
function; otherwise a static error is raised [err:TBD]. The expression in the do
clause is evaluated, resulting in a pending update list. If the target node of any
update primitive on this pending update list is a node that was not newly created in Step 1, a dynamic error is raised [err:TBD]. Let $pul
be the pending update list generated by this step.
The following update operation is invoked: upd:applyUpdates($pul)
. The effect of this operation is to make the updates specified in the do
clause effective on the nodes in the copied node lists.
The return
clause must not contain an updating expression; otherwise a static error is raised [err:XUST0101]. The return
clause is evaluated, and its result is the result of the transform expression. During evaluation of the return
clause, changes applied to copied nodes by the preceding step are visible.
XQuery Update Facility provides extensions to the syntax and semantics of several existing kinds of XQuery expressions, as specified in this section.
[33] | FLWORExpr |
::= | (ForClause | LetClause)+ WhereClause? OrderByClause? ("return" | "do") ExprSingle |
The syntax of the FLWOR expression is extended to include a new clause, called a do
clause, that can be substituted for the return
clause. The semantics of the FLWOR expression are extended as follows:
If the FLWOR expression contains a return
clause, the return
clause must contain a non-updating expression; otherwise, a static error is raised [err:XUST0101]. The FLWOR expression is a non-updating expression, and its semantics are as specified in Section 3.8 of [XQuery 1.0].
If the FLWOR expression contains a do
clause, the do
clause must contain either an updating expression, an empty expression ( )
, or a call to the fn:error
function; otherwise, a static error is raised [err:XUST0101]. The FLWOR expression is an updating expression, and its
semantics are as follows:
The semantics of the for
, let
, where
, and order by
clauses are as specified in Section 3.8 of [XQuery 1.0]. If any of these clauses contains an updating expression, a static error is raised [err:XUST0101]. These clauses generate a stream of tuples of bound variables.
For each tuple generated by the previous step, the expression in the do
clause is evaluated, resulting in a pending update list and an XDM instance.
All the pending update lists generated by the previous step are merged by successive invocations of the upd:mergeUpdates
operation. If the upd:mergeUpdates
operation signals an incompatibility, a dynamic error is raised [err:TBD]. Otherwise, the result of the FLWOR expression is the merged pending update list returned by the final upd:mergeUpdates
operation, and the concatenation of the XDM instances
returned by the evaluations of the do
clauses.
The following example illustrates the use of an updating expression in a FLWOR expression:
Update an inventory of parts according to a set of changes provided in the bound variable $changes
. Both /inventory
and $changes
contain a set of part
elements, each with a partno
and a quantity
.
for $p in /inventory/part let $deltap := $changes/part[partno eq $p/partno] do replace value of {$p/quantity} with $p/quantity + $deltap/quantity
[43] | TypeswitchExpr |
::= | "typeswitch" "(" Expr ")" CaseClause+ "default" ("$" VarName)? ("return" | "do") ExprSingle |
[44] | CaseClause |
::= | "case" ("$" VarName "as")? SequenceType ("return" | "do") ExprSingle |
The syntax of the typeswitch expression is extended to allow each return
clause to be replaced by a do
clause. The semantics of the typeswitch expression are extended as follows (the term "branch" refers to any case
or default
clause in the typeswitch expression):
If any branch contains a return
clause, all branches must contain return
clauses; otherwise a static error is raised [err:TBD]. In this case:
If any branch contains an updating expression, a static error is raised [err:XUST0101].
The typeswitch expression is a non-updating expression and its semantics are as specified in Section 3.12.2 of [XQuery 1.0].
If any branch contains a do
clause, all branches must contain do
clauses; otherwise a static error is raised [err:TBD]. In this case:
Every branch must contain either an updating expression, an empty expression ( )
, or a call to the fn:error
function; otherwise a static error is raised [err:TBD].
The typeswitch expression is an updating expression. Selection of the effective case and binding of variables is performed as specified in Section 3.12.2 of [XQuery 1.0]. The expression in the do
clause of the effective case (or default) is then evaluated, resulting in a pending update list and an XDM instance, which serve as the result of the typeswitch expression.
The semantics of conditional expressions are extended as follows (the term "branch" refers to the then
and else
clauses in the conditional expression):
If at least one branch contains a non-updating expression other than the empty expression ( )
or a call to the fn:error
function, the other branch must contain a non-updating expression; otherwise a static error is raised [err:XUST0101]. In this case, the conditional expression is a
non-updating expression, and its semantics are as specified in Section 3.10 of [XQuery 1.0].
If at least one branch contains an updating expression, the conditional expression is an updating expression. In this case, the test expression is evaluated and the then
or else
clause is selected and evaluated as specified in Section 3.10 of [XQuery 1.0]. The result of the conditional expression is the pending update list and XDM instance returned by the selected branch.
The following example illustrates the use of updating expressions in a conditional expression:
If the element bound to variable $e has a last-updated
attribute, update its value to the current date; otherwise insert such an attribute.
if ($e/@last-updated) then replace value of {$e/last-updated} with fn:currentDate() else insert {attribute last-updated {fn:currentDate()}} into $e
The semantics of comma expressions (composed of one or more expressions concatenated by the comma operator, as described in Section 3.3.1 of [XQuery 1.0]) are extended as follows:
If any operand of the comma expression is an updating expression, the comma expression is an updating expression; otherwise, the comma expression is a non-updating expression.
The XDM instance returned by the comma expression is the concatenation of the XDM instances returned by its operand expressions, as specified in Section 3.3.1 of [XQuery 1.0].
The pending update lists returned by the operand expressions of the comma expression are merged by the upd:mergeUpdates
operation. If the upd:mergeUpdates
operation reports an incompatibility, a dynamic error is raised [err:TBD]. Otherwise, the comma expression returns the merged pending update list returned by the upd:mergeUpdates
operation.
Note:
The comma expression is the only expression that combines an updating expression with a non-updating expression other than ( )
or fn:error()
, thus producing a result that includes both a non-empty XDM instance and a non-empty pending update list. This functionality is still under discussion in the Query Working Group, and may be deleted from the specification or made optional. Public feedback on this functionality is timely and welcome.
The following examples illustrate the use of comma expressions:
This example makes the value of an element empty and gives the element an xsi:nil="true"
attribute. Both of these operations may be necessary in order to preserve the validity of the element.
let $q := /inventory/item[serialno = "123456"]/quantity do replace value of {$q} with ( ), insert {attribute xsi:nil {"true"}} into $q
This example increases the salary of all employees that meet certain criteria, and returns the names of the employees who received salary increases (illustrates a comma expression that combines updating and non-updating expressions):
for $e in //employee do if ($e/sales > $e/quota and fn:currentDate() - $e/last-raise > xdt:dayTimeDuration("P365D")) then (replace value of {$e/salary} with $e/salary * 1.1, replace value of {$e/last-raise} with fn:currentDate(), $e/name) else ( )
The semantics of a parenthesized expression (any XQuery expression enclosed in parentheses) are extended as follows:
The category of a parenthesized expression is the same as the category of its operand expression, which may be an updating expression or a non-updating expression. The result of a parenthesized expression is also the same as the result of its operand expression, which includes both an XDM instance and a pending update list.
[26] | FunctionDecl |
::= | "declare" "updating"? "function" QName "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external") |
The syntax of a function declaration is extended to include an optional keyword: updating
. The semantics of a function declaration are extended as follows:
If external
is not specified:
If updating
is specified, the EnclosedExpr in the function declaration must be an updating expression; otherwise a static error is raised [err:XUST0101].
If updating
is not specified, the EnclosedExpr in the function declaration must be a non-updating expression; otherwise a static error is raised [err:TBD].
If external
is specified:
If updating
is not specified, the pending update list returned by the external function must be empty; otherwise a dynamic error is raised [err:TBD].
The means by which an external function returns an XDM instance and a pending update list is implementation-defined.
The following example illustrates an updating function.
This function takes an element, a QName, and an atomic value. If the given element has an attribute with the given QName, the function updates the attribute with the given value; otherwise it inserts a new attribute with the given name and value.
declare updating function upsert($e as element(), $an as xs:QName, $av as xdt:anyAtomicType) as element() { let $ea := $e/attribute()[fn:node-name(.) = $an] do if (fn:empty($ea)) then insert {attribute {$an} {$av}} into $e else replace value of {$ea} with $av }
The semantics of a function call are extended as follows:
The function call is evaluated as specified in Section 3.1.5 of [XQuery 1.0]. If any input parameter of the function call is an updating expression, a static error is raised [err:XUST0101]. If the called function was declared with the updating
keyword, the function call is an updating
expression. If the called function was declared without the updating
keyword, the function call is a non-updating expression.
The semantics of all XQuery expressions other than FLWOR expressions, typeswitch expressions, conditional expressions, comma expressions, parenthesized expressions, and function calls are extended as follows:
If any operand of this expression is an updating expression, a static error is raised [err:XUST0101].
This section describes the update operations defined by XQuery Update Facility. Although these update operations are described using a functional notation, they are not true functions because many of them have no return value. These update operations are used in defining the semantics of XQuery expressions, but they are not directly available to users.
upd:mergeUpdates( $pul1 as pending-update-list, $pul2 as pending-update-list)
None.
The two pending update lists are merged into a single pending update list containing all the update primitives from both lists. This merged list is returned by the upd:mergeUpdates
function.
Optionally, an implementation may check the two input pending update lists for compatibility, using the compatibility table in 3.5 Compatibility of Update Primitives. The input lists are incompatible if any update primitive on the first list is incompatible with any update primitive on the second list according to the compatibility table. If an implementation discovers an incompatibility, it may signal this incompatibility rather than returning a merged pending update list.
upd:revalidate( $target as node())
$target
must be a document node or an element node.
(To be specified. The intention is to apply schema validation to $target
and its descendants while preserving the identities of the validated nodes. Validation is performed using the in-scope schema definitions in the static context as an effective schema. Some special rules apply as specified in Section 3.13 of [XQuery 1.0]. An error is signaled if validation fails. Error semantics remain to be specified.)
If revalidation mode in the static context is skip
, no validation is performed. If revalidation mode is strict
or lax
, the revalidated element is defined as $target
or (if $target
is a document node) the single element child of $target
[err:TBD]. If revalidation mode is strict
, the revalidated element must have a top-level element declaration in the effective schema, and must conform to this declaration. If revalidation mode
is lax
, the revalidated element must conform to its top-level element declaration if such a declaration exists in the effective schema. If revalidation mode is lax
and there is no top-level
element declaration for the revalidated element, and the revalidated element has an xsi:type
attribute, then the xsi:type
attribute must name a top-level type definition in the effective schema, and the revalidated element must conform to that type.
Note:
After revalidation, the type annotations of the nodes in the validated subtree are consistent with their content. It is expected that implementations will optimize the revalidation process by taking into account which nodes have been modified since they were last validated.
upd:applyUpdates( $pul as pending-update-list)
None.
Checks the update primitives on $pul
for compatibility, using the compatibility table in 3.5 Compatibility of Update Primitives. Signals an incompatibility if any two update primitives on the list are incompatible according to the compatibility table.
The semantics of all the update primitives on $pul
are made effective, in implementation-dependent order.
For each document or element node N
that is the topmost ancestor of the target node of an update primitive on $pul
, invoke upd:revalidate(N)
.
If the resulting XDM instance violates any consistency constraint specified in [XQuery/XPath Data Model (XDM)], an error is signaled.
The update primitives described in this section may be held on pending update lists. When an update primitive is held on a pending update list, its node operands are represented by nodeids. The semantics of an update primitive do not become effective until the update primitive is used in the parameter of a upd:applyUpdates
function.
Two actions called remove-type and set-to-untyped are used in the definitions of the update primitives. These actions are not update primitives themselves because they are never found on a pending update list.
[Definition: Remove-type is an action that is applied to an element or attribute node whose name or content has been modified. The action removes specific type information from the node and its ancestors, pending revalidation.]
The term "remove-type is applied to node N
" is defined as follows:
If N
is an element node, its properties are changed as follows:
If type-name
is not equal to xdt:untyped
, then
type-name
is set to xs:anyType
If the parent of N
is an element node, then remove-type is invoked on the parent of N
.
string-value
is set equal to the concatenated contents of the text node descendants, in document order.
typed-value
is set equal to the string-value
property, as an instance of xdt:untypedAtomic
.
Note:
The data model allows some flexibility to implementations regarding whether string-value
and/or typed-value
are stored or computed dynamically.
nilled
, is-id
, and is-idrefs
are set to false
.
If N
is an attribute node, its properties are changed as follows:
type-name
is set to xdt:untypedAtomic
.
typed-value
is set equal to the string-value
property, as an instance of xdt:untypedAtomic
.
is-id
and is-idrefs
are set to false
.
remove-type is invoked on the parent of N
(if any).
[Definition: Set-to-untyped is an action that is applied to an element or attribute node that has been inserted into an untyped context, which requires that the node and its descendants be untyped as well.]
The term "set-to-untyped is applied to node N
" is defined as follows:
If N
is an element node, its properties are changed as follows:
type-name
is set to xdt:untyped
.
typed-value
is set equal to the string-value
property, as an instance of xdt:untypedAtomic
.
Note:
The data model allows some flexibility to implementations regarding whether string-value
and/or typed-value
are stored or computed dynamically.
nilled
, is-id
, and is-idrefs
are set to false
.
Set-to-untyped is invoked on the attributes and child element nodes of N
.
If N
is an attribute node, its properties are changed as follows:
type-name
is set to xdt:untypedAtomic
.
typed-value
is set equal to the string-value
property, as an instance of xdt:untypedAtomic
.
is-id
and is-idrefs
are set to false
.
upd:insertBefore( $target as node(), $content as node()+)
Inserts $content
immediately before $target
.
$target
must be an element, text, processing instruction, or comment node with a non-empty parent
property. $content
must be a sequence containing only element, text, processing instruction, and comment nodes.
Effects on nodes in $content
:
For each node in $content
, the parent
property is set to parent($target)
.
If the type-name
property of parent($target)
is xdt:untyped
, then set-to-untyped is applied to each element or attribute node in $content
.
Effects on parent($target)
:
The children
property of parent($target)
is modified to add the nodes in $content
just before $target
, preserving their order.
If, as a result of the previous step, the children
property of parent($target)
contains adjacent text nodes, these adjacent text nodes are merged into a single text node. The string-value of the resulting text node is the concatenated string-values of the adjacent text nodes, with no intervening space added. The nodeid of the resulting text node is implementation-dependent.
If at least one of the nodes in $content
is an element or text node, remove-type is invoked on parent($target)
.
upd:insertAfter( $target as node(), $content as node()+)
Inserts $content
immediately after $target
.
$target
must be an element, text, processing instruction, or comment node with a non-empty parent
property. $content
must be a sequence containing only element, text, processing instruction, and comment nodes.
The semantics of upd:insertAfter
are identical to the semantics of upd:insertBefore
, except that Rule 2a is changed as follows:
The children
property of parent($target)
is modified to add the nodes in $content
just after $target
, preserving their order.
upd:insertInto( $target as node(), $content as node()+)
Inserts $content
as the children of $target
, in an implementation-defined position.
$target
must be an element or document node. $content
must be a sequence containing only element, text, processing instruction, and comment nodes.
The semantics of upd:insertIntoAsLast
are identical to the semantics of upd:insertBefore
, except that $target
is substuted everywhere for parent($target)
, and Rule 2a is changed as follows:
The children
property of $target
is changed to include the nodes in $content
. The order among the new children, and their position within the parent node, is implementation-dependent.
upd:insertIntoAsLast( $target as node(), $content as node()+)
Inserts $content
as the last children of $target
.
$target
must be an element or document node. $content
must be a sequence containing only element, text, processing instruction, and comment nodes.
The semantics of upd:insertIntoAsLast
are identical to the semantics of upd:insertBefore
, except that $target
is substuted everywhere for parent($target)
, and Rule 2a is changed as follows:
The children
property of $target
is changed to include the nodes in $content
as the last children, preserving their order.
upd:insertAttributes( $target as element(), $content as attribute()+)
Inserts $content
as attributes of $target
.
None
For each node A
in $content
:
The parent
property of A
is set to $target
.
If the type-name
property of $target
is xdt:untyped
, then set-to-untyped is applied to A
.
The following properties of $target
are changed:
attributes
: Modified to include the nodes in $content
.
namespaces:
Modified to include namespace bindings for any attribute namespace prefixes in $content
that did not already have bindings.
Remove-type is applied to $target
.
upd:delete( $target as node())
Deletes $target
and all its attributes and descendants.
None
$target
and all of its attributes and descendants (if any) are deleted from their XDM instance.
Note:
The effect on variable bindings in which the deleted node participates, and the effect on available documents and collections, are under discussion.
Effect on parent($target)
, if any:
If $target
is an attribute node, attributes
is modified to delete $target
.
If $target
is a non-attribute node, children
is modified to delete $target
.
If, as a result of the previous step, the children
property of parent($target)
contains adjacent text nodes, these adjacent text nodes are merged into a single text node. The string-value of the resulting text node is the concatenated string-values of the adjacent text nodes, with no intervening space added. The nodeid of the resulting text node is implementation-dependent.
If $target
is an element, attribute, or text node, and parent($target)
is an element node, then remove-type is applied to parent($target)
.
upd:replaceValue( $target as node(), $string-value as xs:string)
Replaces the string value of $target
with $string-value
.
$target
must be an attribute, text, comment, or processing instruction node.
If $target
is an attribute node:
string-value
of $target
is set to $string-value
.
remove-type is applied to $target
.
If $target
is a text, comment, or processing instruction node: content
of $target
is set to $string-value
.
If $target
is a text node, remove-type is applied to parent($target)
.
upd:rename( $target as node(), $newName as xs:QName)
Changes the node-name of $target
to $newName
.
$target
must be an element, attribute, or processing instruction node.
If $target
is an element node:
node-name
of $target
is set to $newName
.
Remove-type is applied to $target
.
If $target
is an attribute node:
node-name
of $target
is set to $newName
.
Remove-type is applied to $target
.
If $newName
is xml:id
, the is-id
property of $target
is set to true
.
The namespaces
property of parent($target)
is modified to include a namespace binding derived from $newName
, if this binding did not already exist.
If $target
is a processing instruction node, its target
property is set to $newName
.
delete(t2) | rename(t2,r2) | repVal(t2,r2) | insBef(t2,r2) | insAft(t2,r2) | insInto(t2,r2) | insAsLast(t2,r2) | insAttrs(t2,r2) | |
delete(t1) | yes | yes | yes | yes | yes | yes | yes | yes |
rename(t1,r1) | yes | no (1) | yes | yes | yes | yes | yes | yes |
repVal(t1,r1) | yes | yes | no(1) | yes | yes | yes | yes | yes |
insBef(t1,r1) | yes | yes | yes | no (1) | yes | yes | yes | yes |
insAft(t1,r1) | yes | yes | yes | yes | no (1) | yes | yes | yes |
insInto(t1,r1) | yes | yes | yes | yes | yes | yes | no (1) | yes |
insAsLast(t1,r1) | yes | yes | yes | yes | yes | no (1) | no (1) | yes |
insAttrs(t1,r1) | yes | yes | yes | yes | yes | yes | yes | yes |
Not compatible if t1 is t2.
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" "$" QName TypeDeclaration? ((":=" ExprSingle) | "external") |
|
[25] | ConstructionDecl |
::= | "declare" "construction" ("strip" | "preserve") |
|
[26] | FunctionDecl |
::= | "declare" "updating"? "function" QName "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external") |
|
[27] | ParamList |
::= | Param ("," Param)* |
|
[28] | Param |
::= | "$" QName TypeDeclaration? |
|
[29] | EnclosedExpr |
::= | "{" Expr "}" |
|
[30] | QueryBody |
::= | Expr |
|
[31] | Expr |
::= | ExprSingle ("," ExprSingle)* |
|
[32] | ExprSingle |
::= | FLWORExpr |
|
[33] | FLWORExpr |
::= | (ForClause | LetClause)+ WhereClause? OrderByClause? ("return" | "do") ExprSingle |
|
[34] | ForClause |
::= | "for" "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle ("," "$" VarName TypeDeclaration? PositionalVar? "in" ExprSingle)* |
|
[35] | PositionalVar |
::= | "at" "$" VarName |
|
[36] | LetClause |
::= | "let" "$" VarName TypeDeclaration? ":=" ExprSingle ("," "$" VarName TypeDeclaration? ":=" ExprSingle)* |
|
[37] | WhereClause |
::= | "where" ExprSingle |
|
[38] | OrderByClause |
::= | (("order" "by") | ("stable" "order" "by")) OrderSpecList |
|
[39] | OrderSpecList |
::= | OrderSpec ("," OrderSpec)* |
|
[40] | OrderSpec |
::= | ExprSingle OrderModifier |
|
[41] | OrderModifier |
::= | ("ascending" | "descending")? ("empty" ("greatest" | "least"))? ("collation" URILiteral)? |
|
[42] | QuantifiedExpr |
::= | ("some" | "every") "$" VarName TypeDeclaration? "in" ExprSingle ("," "$" VarName TypeDeclaration? "in" ExprSingle)* "satisfies" ExprSingle |
|
[43] | TypeswitchExpr |
::= | "typeswitch" "(" Expr ")" CaseClause+ "default" ("$" VarName)? ("return" | "do") ExprSingle |
|
[44] | CaseClause |
::= | "case" ("$" VarName "as")? SequenceType ("return" | "do") ExprSingle |
|
[45] | IfExpr |
::= | "if" "(" Expr ")" "then" ExprSingle "else" ExprSingle |
|
[46] | OrExpr |
::= | AndExpr ( "or" AndExpr )* |
|
[47] | AndExpr |
::= | ComparisonExpr ( "and" ComparisonExpr )* |
|
[48] | ComparisonExpr |
::= | RangeExpr ( (ValueComp |
|
[49] | RangeExpr |
::= | AdditiveExpr ( "to" AdditiveExpr )? |
|
[50] | AdditiveExpr |
::= | MultiplicativeExpr ( ("+" | "-") MultiplicativeExpr )* |
|
[51] | MultiplicativeExpr |
::= | UnionExpr ( ("*" | "div" | "idiv" | "mod") UnionExpr )* |
|
[52] | UnionExpr |
::= | IntersectExceptExpr ( ("union" | "|") IntersectExceptExpr )* |
|
[53] | IntersectExceptExpr |
::= | InstanceofExpr ( ("intersect" | "except") InstanceofExpr )* |
|
[54] | InstanceofExpr |
::= | TreatExpr ( "instance" "of" SequenceType )? |
|
[55] | TreatExpr |
::= | CastableExpr ( "treat" "as" SequenceType )? |
|
[56] | CastableExpr |
::= | CastExpr ( "castable" "as" SingleType )? |
|
[57] | CastExpr |
::= | UnaryExpr ( "cast" "as" SingleType )? |
|
[58] | UnaryExpr |
::= | ("-" | "+")* ValueExpr |
|
[59] | ValueExpr |
::= | ValidateExpr | PathExpr | ExtensionExpr |
|
[60] | GeneralComp |
::= | "=" | "!=" | "<" | "<=" | ">" | ">=" |
|
[61] | ValueComp |
::= | "eq" | "ne" | "lt" | "le" | "gt" | "ge" |
|
[62] | NodeComp |
::= | "is" | "<<" | ">>" |
|
[63] | ValidateExpr |
::= | "validate" ValidationMode? "{" Expr "}" |
|
[64] | ValidationMode |
::= | "lax" | "strict" |
|
[65] | ExtensionExpr |
::= | Pragma+ "{" Expr? "}" |
|
[66] | Pragma |
::= | "(#" S? QName PragmaContents "#)" |
/* ws: explicitXQ */ |
[67] | PragmaContents |
::= | (Char* - (Char* '#)' Char*)) |
|
[68] | PathExpr |
::= | ("/" RelativePathExpr?) |
/* gn: leading-lone-slashXQ */ |
[69] | RelativePathExpr |
::= | StepExpr (("/" | "//") StepExpr)* |
|
[70] | StepExpr |
::= | FilterExpr | AxisStep |
|
[71] | AxisStep |
::= | (ReverseStep | ForwardStep) PredicateList |
|
[72] | ForwardStep |
::= | (ForwardAxis NodeTest) | AbbrevForwardStep |
|
[73] | ForwardAxis |
::= | ("child" "::") |
|
[74] | AbbrevForwardStep |
::= | "@"? NodeTest |
|
[75] | ReverseStep |
::= | (ReverseAxis NodeTest) | AbbrevReverseStep |
|
[76] | ReverseAxis |
::= | ("parent" "::") |
|
[77] | AbbrevReverseStep |
::= | ".." |
|
[78] | NodeTest |
::= | KindTest | NameTest |
|
[79] | NameTest |
::= | QName | Wildcard |
|
[80] | Wildcard |
::= | "*" |
/* ws: explicitXQ */ |
[81] | FilterExpr |
::= | PrimaryExpr PredicateList |
|
[82] | PredicateList |
::= | Predicate* |
|
[83] | Predicate |
::= | "[" Expr "]" |
|
[84] | PrimaryExpr |
::= | Literal | VarRef | ParenthesizedExpr | ContextItemExpr | FunctionCall | OrderedExpr | UnorderedExpr | Constructor |
|
[85] | Literal |
::= | NumericLiteral | StringLiteral |
|
[86] | NumericLiteral |
::= | IntegerLiteral | DecimalLiteral | DoubleLiteral |
|
[87] | VarRef |
::= | "$" VarName |
|
[88] | VarName |
::= | QName |
|
[89] | ParenthesizedExpr |
::= | "(" Expr? ")" |
|
[90] | ContextItemExpr |
::= | "." |
|
[91] | OrderedExpr |
::= | "ordered" "{" Expr "}" |
|
[92] | UnorderedExpr |
::= | "unordered" "{" Expr "}" |
|
[93] | FunctionCall |
::= | QName "(" (ExprSingle ("," ExprSingle)*)? ")" |
/* gn: reserved-function-namesXQ */ |
/* gn: parensXQ */ | ||||
[94] | Constructor |
::= | DirectConstructor |
|
[95] | DirectConstructor |
::= | DirElemConstructor |
|
[96] | DirElemConstructor |
::= | "<" QName DirAttributeList ("/>" | (">" DirElemContent* "</" QName S? ">")) |
/* ws: explicitXQ */ |
[97] | DirAttributeList |
::= | (S (QName S? "=" S? DirAttributeValue)?)* |
/* ws: explicitXQ */ |
[98] | DirAttributeValue |
::= | ('"' (EscapeQuot | QuotAttrValueContent)* '"') |
/* ws: explicitXQ */ |
[99] | QuotAttrValueContent |
::= | QuotAttrContentChar |
|
[100] | AposAttrValueContent |
::= | AposAttrContentChar |
|
[101] | DirElemContent |
::= | DirectConstructor |
|
[102] | CommonContent |
::= | PredefinedEntityRef | CharRef | "{{" | "}}" | EnclosedExpr |
|
[103] | DirCommentConstructor |
::= | "<!--" DirCommentContents "-->" |
/* ws: explicitXQ */ |
[104] | DirCommentContents |
::= | ((Char - '-') | ('-' (Char - '-')))* |
/* ws: explicitXQ */ |
[105] | DirPIConstructor |
::= | "<?" PITarget (S DirPIContents)? "?>" |
/* ws: explicitXQ */ |
[106] | DirPIContents |
::= | (Char* - (Char* '?>' Char*)) |
/* ws: explicitXQ */ |
[107] | CDataSection |
::= | "<![CDATA[" CDataSectionContents "]]>" |
/* ws: explicitXQ */ |
[108] | CDataSectionContents |
::= | (Char* - (Char* ']]>' Char*)) |
/* ws: explicitXQ */ |
[109] | ComputedConstructor |
::= | CompDocConstructor |
|
[110] | CompDocConstructor |
::= | "document" "{" Expr "}" |
|
[111] | CompElemConstructor |
::= | "element" (QName | ("{" Expr "}")) "{" ContentExpr? "}" |
|
[112] | ContentExpr |
::= | Expr |
|
[113] | CompAttrConstructor |
::= | "attribute" (QName | ("{" Expr "}")) "{" Expr? "}" |
|
[114] | CompTextConstructor |
::= | "text" "{" Expr "}" |
|
[115] | CompCommentConstructor |
::= | "comment" "{" Expr "}" |
|
[116] | CompPIConstructor |
::= | "processing-instruction" (NCName | ("{" Expr "}")) "{" Expr? "}" |
|
[117] | SingleType |
::= | AtomicType "?"? |
|
[118] | TypeDeclaration |
::= | "as" SequenceType |
|
[119] | SequenceType |
::= | ("empty-sequence" "(" ")") |
|
[120] | OccurrenceIndicator |
::= | "?" | "*" | "+" |
/* gn: occurrence-indicatorsXQ */ |
[121] | ItemType |
::= | KindTest | ("item" "(" ")") | AtomicType |
|
[122] | AtomicType |
::= | QName |
|
[123] | KindTest |
::= | DocumentTest |
|
[124] | AnyKindTest |
::= | "node" "(" ")" |
|
[125] | DocumentTest |
::= | "document-node" "(" (ElementTest | SchemaElementTest)? ")" |
|
[126] | TextTest |
::= | "text" "(" ")" |
|
[127] | CommentTest |
::= | "comment" "(" ")" |
|
[128] | PITest |
::= | "processing-instruction" "(" (NCName | StringLiteral)? ")" |
|
[129] | AttributeTest |
::= | "attribute" "(" (AttribNameOrWildcard ("," TypeName)?)? ")" |
|
[130] | AttribNameOrWildcard |
::= | AttributeName | "*" |
|
[131] | SchemaAttributeTest |
::= | "schema-attribute" "(" AttributeDeclaration ")" |
|
[132] | AttributeDeclaration |
::= | AttributeName |
|
[133] | ElementTest |
::= | "element" "(" (ElementNameOrWildcard ("," TypeName "?"?)?)? ")" |
|
[134] | ElementNameOrWildcard |
::= | ElementName | "*" |
|
[135] | SchemaElementTest |
::= | "schema-element" "(" ElementDeclaration ")" |
|
[136] | ElementDeclaration |
::= | ElementName |
|
[137] | AttributeName |
::= | QName |
|
[138] | ElementName |
::= | QName |
|
[139] | TypeName |
::= | QName |
|
[140] | URILiteral |
::= | StringLiteral |
|
[141] | RevalidationDecl |
::= | "declare" "revalidation" ("strict" | "lax" | "skip") |
|
[142] | TargetExpr |
::= | ExprSingle |
|
[143] | SourceExpr |
::= | ExprSingle |
|
[144] | NewNameExpr |
::= | ExprSingle |
|
[145] | InsertExpr |
::= | "insert" (DirectConstructor | ("{" SourceExpr "}")) ((("as" ("first" | "last"))? "into") |
|
[146] | DeleteExpr |
::= | "delete" "{" TargetExpr "}" |
|
[147] | ReplaceExpr |
::= | "replace" ("value" "of")? "{" TargetExpr "}" "with" ExprSingle ("," "{" TargetExpr "}" "with" ExprSingle)* |
|
[148] | RenameExpr |
::= | "rename" "{" TargetExpr "}" "to" NewNameExpr |
|
[149] | TransformExpr |
::= | "transform" "copy" "$" VarName ":=" ExprSingle ("," "$" VarName ":=" ExprSingle)* "do" ExprSingle "return" ExprSingle |
[150] | IntegerLiteral |
::= | Digits |
|
[151] | DecimalLiteral |
::= | ("." Digits) | (Digits "." [0-9]*) |
/* ws: explicitXQ */ |
[152] | DoubleLiteral |
::= | (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits |
/* ws: explicitXQ */ |
[153] | StringLiteral |
::= | ('"' (PredefinedEntityRef | CharRef | EscapeQuot | [^"&])* '"') | ("'" (PredefinedEntityRef | CharRef | EscapeApos | [^'&])* "'") |
/* ws: explicitXQ */ |
[154] | PredefinedEntityRef |
::= | "&" ("lt" | "gt" | "amp" | "quot" | "apos") ";" |
/* ws: explicitXQ */ |
[155] | EscapeQuot |
::= | '""' |
|
[156] | EscapeApos |
::= | "''" |
|
[157] | ElementContentChar |
::= | Char - [{}<&] |
|
[158] | QuotAttrContentChar |
::= | Char - ["{}<&] |
|
[159] | AposAttrContentChar |
::= | Char - ['{}<&] |
|
[160] | Comment |
::= | "(:" (CommentContents | Comment)* ":)" |
/* ws: explicitXQ */ |
/* gn: commentsXQ */ | ||||
[161] | PITarget |
::= | [http://www.w3.org/TR/REC-xml#NT-PITarget]XML |
/* gn: xml-versionXQ */ |
[162] | CharRef |
::= | [http://www.w3.org/TR/REC-xml#NT-CharRef]XML |
/* gn: xml-versionXQ */ |
[163] | QName |
::= | [http://www.w3.org/TR/REC-xml-names/#NT-QName]Names |
/* gn: xml-versionXQ */ |
[164] | NCName |
::= | [http://www.w3.org/TR/REC-xml-names/#NT-NCName]Names |
/* gn: xml-versionXQ */ |
[165] | S |
::= | [http://www.w3.org/TR/REC-xml#NT-S]XML |
/* gn: xml-versionXQ */ |
[166] | 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 Update extensions.
[167] | Digits |
::= | [0-9]+ |
[168] | CommentContents |
::= | (Char+ - (Char* ('(:' | ':)') Char*)) |
It is a static error if an updating expression is used in any position other than one of the following:
The do
clause of a transform expression.
The do
clause of a FLWOR expression.
The do
clauses of a typeswitch expression in which every case
clause and the default
clause contain do
clauses.
The then
and else
clauses of a conditional statement in which both the then
and else
clauses contain either an updating expression, an empty expression ( )
, or a call to the fn:error
function.
An operand of a comma expression.
The content of a parenthesized expression.
The body of a function declaration in which the keyword updating
is specified.
The term data model refers to the data model specified by [XQuery/XPath Data Model (XDM)].
A non-updating expression is an expression that cannot modify the state of an existing node.
A pending update list is an unordered collection of update primitives, which represent node state changes that have not yet been applied.
Remove-type is an action that is applied to an element or attribute node whose name or content has been modified. The action removes specific type information from the node and its ancestors, pending revalidation.
A replacement is an operation that replaces a node or modifies the value of a node.
A revalidation declaration sets the revalidation mode in the static context, overriding any implementation-defined default.
Revalidation mode, which may be strict
, lax
, or skip
, is a component of the static context that controls the behavior of the upd:revalidate
operation.
Set-to-untyped is an action that is applied to an element or attribute node that has been inserted into an untyped context, which requires that the node and its descendants be untyped as well.
The upd:applyUpdates
operation determines the scope within which all expressions are evaluated before any updates are applied. This is sometimes called the scope of snapshot semantics.
The first argument of an update primitive, called its target node, is the principal node to be affected by the update primitive.
Update operations are used in defining the semantics of XQuery updates, but are not directly available to users. Update operations are defined in 3 Update Operations.
Each update primitive represents a node state change that has not yet been applied.
An updating expression is an expression that can modify the state of an existing node.
The term XDM instance denotes an unconstrained sequence of zero or more nodes and/or atomic values as defined by the data model.
Within this document, the term XQuery refers to the language specified by [XQuery 1.0].