W3C

XQuery Update Facility

W3C Working Draft 27 January 2006

This version:
http://www.w3.org/TR/2006/WD-xqupdate-20060127/
Latest version:
http://www.w3.org/TR/xqupdate/
Editors:
Don Chamberlin, IBM Almaden Research Center <chamberlin@almaden.ibm.com>
Daniela Florescu, Oracle Corporation <dana.florescu@oracle.com>
Jonathan Robie, DataDirect Technologies <jonathan.robie@datadirect.com>

Abstract

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.

Status of this Document

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

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

Table of Contents

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

Appendices

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)


1 Introduction

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:

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

2 Extensions to XQuery 1.0

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:

The extensions to XQuery 1.0 provided by XQuery Update Facility may be characterized as follows:

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

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

2.1 Extensions to the Processing Model

XQuery Update Facility defines the following extensions to the XQuery processing model:

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

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

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

    2. upd:mergeUpdates is an update operation that operates on two pending update lists, merging them into a single pending update list.

    3. upd:applyUpdates is an update operation that makes the update primitives in a pending update list effective by applying them to an XDM instance.

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

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

2.2 Extensions to the Prolog

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

2.3 New Kinds of Expressions

[32]    ExprSingle    ::=    FLWORExpr
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| InsertExpr
| DeleteExpr
| RenameExpr
| ReplaceExpr
| TransformExpr
| OrExpr

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.

2.3.1 Insert

[145]    InsertExpr    ::=    "insert" (DirectConstructor | ("{" SourceExpr "}")) ((("as" ("first" | "last"))? "into")
| "after"
| "before") TargetExpr
[143]    SourceExpr    ::=    ExprSingle
[142]    TargetExpr    ::=    ExprSingle
[95]    DirectConstructor    ::=    DirElemConstructor
| DirCommentConstructor
| DirPIConstructor

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:

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

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

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

  4. The result of the insert expression is a pending update list constructed as follows:

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

      1. If $alist is not empty, upd:insertAttributes($target, $alist)

      2. If $clist is not empty, upd:insertBefore($child, $clist)

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

      1. If $alist is not empty, upd:insertAttributes($target, $alist)

      2. If $clist is not empty, upd:insertIntoAsLast($target, $clist)

    3. If into is specified and neither as first nor as last is specified, the pending update list consists of the following update primitives:

      1. If $alist is not empty, upd:insertAttributes($target, $alist)

      2. If $clist is not empty, upd:insertInto($target, $clist)

    4. If before is specified, let $parent be the parent node of $target. The pending update list consists of the following update primitives:

      1. If $alist is not empty, upd:insertAttributes($parent, $alist)

      2. If $clist is not empty, upd:insertBefore($target, $clist)

    5. If after is specified, let $parent be the parent node of $target. The pending update list consists of the following update primitives:

      1. If $alist is not empty, upd:insertAttributes($parent, $alist)

      2. If $clist is not empty, upd:insertAfter($target, $clist)

2.3.2 Delete

[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:

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

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

2.3.3 Replace

[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:

  1. The individual replacements can be processed in any order. Each replacement is processed as follows:

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

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

    3. If $target is an element, text, comment, or processing instruction node, the replacement generates a pending update list consisting of the following update primitives:

      1. upd:insertAttributes($parent, $alist)

      2. upd:insertBefore($target, $clist)

      3. upd:delete($target)

    4. If $target is an attribute node, the replacement generates a pending update list consisting of the following update primitives:

      1. upd:insertAttributes($parent, $alist)

      2. upd:insertIntoAsLast($parent, $clist)

      3. upd:delete($target)

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

  1. The individual replacements can be processed in any order. Each replacement is processed as follows:

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

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

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

      1. For each node $cnode in $clist, upd:delete($cnode).

      2. upd:insertIntoAsLast($target, $text)

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

    5. If $target is a document node, a type error is raised [err:TBD].

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

2.3.4 Rename

[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:

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

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

  3. The result of the rename expression is a pending update list containing the following update primitive: upd:rename($target, $QName).

2.3.5 Transform

[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:

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

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

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

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

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

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

2.4 Extensions to Existing Expressions

XQuery Update Facility provides extensions to the syntax and semantics of several existing kinds of XQuery expressions, as specified in this section.

2.4.1 FLWOR Expression

[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:

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

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

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

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

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

2.4.2 Typeswitch Expression

[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):

  1. If any branch contains a return clause, all branches must contain return clauses; otherwise a static error is raised [err:TBD]. In this case:

    1. If any branch contains an updating expression, a static error is raised [err:XUST0101].

    2. The typeswitch expression is a non-updating expression and its semantics are as specified in Section 3.12.2 of [XQuery 1.0].

  2. If any branch contains a do clause, all branches must contain do clauses; otherwise a static error is raised [err:TBD]. In this case:

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

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

2.4.3 Conditional Expression

The semantics of conditional expressions are extended as follows (the term "branch" refers to the then and else clauses in the conditional expression):

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

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

2.4.4 Comma Expression

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:

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

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

  3. 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 ( )
    

2.4.5 Parenthesized Expression

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.

2.4.6 Function Declaration

[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:

  1. If external is not specified:

    1. If updating is specified, the EnclosedExpr in the function declaration must be an updating expression; otherwise a static error is raised [err:XUST0101].

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

  2. If external is specified:

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

2.4.7 Function Call

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.

2.4.8 Other Expressions

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

3 Update Operations

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.

3.1 upd:mergeUpdates

Parameters
upd:mergeUpdates(
   $pul1 as pending-update-list,
   $pul2 as pending-update-list)
Constraints

None.

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

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

3.2 upd:revalidate

Parameters
upd:revalidate(
   $target as node())
Constraints

$target must be a document node or an element node.

Semantics

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

3.3 upd:applyUpdates

Parameters
upd:applyUpdates(
   $pul as pending-update-list)
Constraints

None.

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

  2. The semantics of all the update primitives on $pul are made effective, in implementation-dependent order.

  3. 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).

  4. If the resulting XDM instance violates any consistency constraint specified in [XQuery/XPath Data Model (XDM)], an error is signaled.

3.4 Update Primitives

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:

  1. If N is an element node, its properties are changed as follows:

    1. If type-name is not equal to xdt:untyped, then

      1. type-name is set to xs:anyType

      2. If the parent of N is an element node, then remove-type is invoked on the parent of N.

    2. string-value is set equal to the concatenated contents of the text node descendants, in document order.

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

    4. nilled, is-id, and is-idrefs are set to false.

  2. If N is an attribute node, its properties are changed as follows:

    1. type-name is set to xdt:untypedAtomic.

    2. typed-value is set equal to the string-value property, as an instance of xdt:untypedAtomic.

    3. is-id and is-idrefs are set to false.

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

  1. If N is an element node, its properties are changed as follows:

    1. type-name is set to xdt:untyped.

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

    3. nilled, is-id, and is-idrefs are set to false.

    4. Set-to-untyped is invoked on the attributes and child element nodes of N.

  2. If N is an attribute node, its properties are changed as follows:

    1. type-name is set to xdt:untypedAtomic.

    2. typed-value is set equal to the string-value property, as an instance of xdt:untypedAtomic.

    3. is-id and is-idrefs are set to false.

3.4.1 upd:insertBefore

Parameters
upd:insertBefore(
   $target as node(),
   $content as node()+)
Summary

Inserts $content immediately before $target.

Constraints

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

Semantics
  1. Effects on nodes in $content:

    1. For each node in $content, the parent property is set to parent($target).

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

  2. Effects on parent($target):

    1. The children property of parent($target) is modified to add the nodes in $content just before $target, preserving their order.

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

    3. If at least one of the nodes in $content is an element or text node, remove-type is invoked on parent($target).

3.4.2 upd:insertAfter

Parameters
upd:insertAfter(
   $target as node(),
   $content as node()+)
Summary

Inserts $content immediately after $target.

Constraints

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

Semantics

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.

3.4.3 upd:insertInto

Parameters
upd:insertInto(
   $target as node(),
   $content as node()+)
Summary

Inserts $content as the children of $target, in an implementation-defined position.

Constraints

$target must be an element or document node. $content must be a sequence containing only element, text, processing instruction, and comment nodes.

Semantics

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.

3.4.4 upd:insertIntoAsLast

Parameters
upd:insertIntoAsLast(
   $target as node(),
   $content as node()+)
Summary

Inserts $content as the last children of $target.

Constraints

$target must be an element or document node. $content must be a sequence containing only element, text, processing instruction, and comment nodes.

Semantics

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.

3.4.5 upd:insertAttributes

Parameters
upd:insertAttributes(
   $target as element(),
   $content as attribute()+)
Summary

Inserts $content as attributes of $target.

Constraints

None

Semantics
  1. For each node A in $content:

    1. The parent property of A is set to $target.

    2. If the type-name property of $target is xdt:untyped, then set-to-untyped is applied to A.

  2. The following properties of $target are changed:

    1. attributes: Modified to include the nodes in $content.

    2. namespaces: Modified to include namespace bindings for any attribute namespace prefixes in $content that did not already have bindings.

    3. Remove-type is applied to $target.

3.4.6 upd:delete

Parameters
upd:delete(
   $target as node())
Summary

Deletes $target and all its attributes and descendants.

Constraints

None

Semantics
  1. $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.

  2. Effect on parent($target), if any:

    1. If $target is an attribute node, attributes is modified to delete $target.

    2. If $target is a non-attribute node, children is modified to delete $target.

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

    4. If $target is an element, attribute, or text node, and parent($target) is an element node, then remove-type is applied to parent($target).

3.4.7 upd:replaceValue

Parameters
upd:replaceValue(
   $target as node(),
   $string-value as xs:string)
Summary

Replaces the string value of $target with $string-value.

Constraints

$target must be an attribute, text, comment, or processing instruction node.

Semantics
  1. If $target is an attribute node:

    1. string-value of $target is set to $string-value.

    2. remove-type is applied to $target.

  2. If $target is a text, comment, or processing instruction node: content of $target is set to $string-value.

  3. If $target is a text node, remove-type is applied to parent($target).

3.4.8 upd:rename

Parameters
upd:rename(
   $target as node(),
   $newName as xs:QName)
Summary

Changes the node-name of $target to $newName.

Constraints

$target must be an element, attribute, or processing instruction node.

Semantics
  1. If $target is an element node:

    1. node-name of $target is set to $newName.

    2. Remove-type is applied to $target.

  2. If $target is an attribute node:

    1. node-name of $target is set to $newName.

    2. Remove-type is applied to $target.

    3. If $newName is xml:id, the is-id property of $target is set to true.

    4. The namespaces property of parent($target) is modified to include a namespace binding derived from $newName, if this binding did not already exist.

  3. If $target is a processing instruction node, its target property is set to $newName.

3.5 Compatibility of Update Primitives

Compatibility of Update Primitives
  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
  1. Not compatible if t1 is t2.

A EBNF for XQuery 1.0 Grammar with Update extensions

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

[1]    Module    ::=    VersionDecl? (LibraryModule | MainModule)
[2]    VersionDecl    ::=    "xquery" "version" StringLiteral ("encoding" StringLiteral)? Separator
[3]    MainModule    ::=    Prolog QueryBody
[4]    LibraryModule    ::=    ModuleDecl Prolog
[5]    ModuleDecl    ::=    "module" "namespace" NCName "=" URILiteral Separator
[6]    Prolog    ::=    ((DefaultNamespaceDecl | Setter | NamespaceDecl | Import) Separator)* ((VarDecl | FunctionDecl | OptionDecl) Separator)*
[7]    Setter    ::=    BoundarySpaceDecl | DefaultCollationDecl | BaseURIDecl | ConstructionDecl | OrderingModeDecl | EmptyOrderDecl | RevalidationDecl | CopyNamespacesDecl
[8]    Import    ::=    SchemaImport | ModuleImport
[9]    Separator    ::=    ";"
[10]    NamespaceDecl    ::=    "declare" "namespace" NCName "=" URILiteral
[11]    BoundarySpaceDecl    ::=    "declare" "boundary-space" ("preserve" | "strip")
[12]    DefaultNamespaceDecl    ::=    "declare" "default" ("element" | "function") "namespace" URILiteral
[13]    OptionDecl    ::=    "declare" "option" QName StringLiteral
[14]    OrderingModeDecl    ::=    "declare" "ordering" ("ordered" | "unordered")
[15]    EmptyOrderDecl    ::=    "declare" "default" "order" "empty" ("greatest" | "least")
[16]    CopyNamespacesDecl    ::=    "declare" "copy-namespaces" PreserveMode "," InheritMode
[17]    PreserveMode    ::=    "preserve" | "no-preserve"
[18]    InheritMode    ::=    "inherit" | "no-inherit"
[19]    DefaultCollationDecl    ::=    "declare" "default" "collation" URILiteral
[20]    BaseURIDecl    ::=    "declare" "base-uri" URILiteral
[21]    SchemaImport    ::=    "import" "schema" SchemaPrefix? URILiteral ("at" URILiteral ("," URILiteral)*)?
[22]    SchemaPrefix    ::=    ("namespace" NCName "=") | ("default" "element" "namespace")
[23]    ModuleImport    ::=    "import" "module" ("namespace" NCName "=")? URILiteral ("at" URILiteral ("," URILiteral)*)?
[24]    VarDecl    ::=    "declare" "variable" "$" 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
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| InsertExpr
| DeleteExpr
| RenameExpr
| ReplaceExpr
| TransformExpr
| OrExpr
[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
| GeneralComp
| NodeComp) RangeExpr )?
[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?)
| ("//" RelativePathExpr)
| 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" "::")
| ("descendant" "::")
| ("attribute" "::")
| ("self" "::")
| ("descendant-or-self" "::")
| ("following-sibling" "::")
| ("following" "::")
[74]    AbbrevForwardStep    ::=    "@"? NodeTest
[75]    ReverseStep    ::=    (ReverseAxis NodeTest) | AbbrevReverseStep
[76]    ReverseAxis    ::=    ("parent" "::")
| ("ancestor" "::")
| ("preceding-sibling" "::")
| ("preceding" "::")
| ("ancestor-or-self" "::")
[77]    AbbrevReverseStep    ::=    ".."
[78]    NodeTest    ::=    KindTest | NameTest
[79]    NameTest    ::=    QName | Wildcard
[80]    Wildcard    ::=    "*"
| (NCName ":" "*")
| ("*" ":" NCName)
/* 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
| ComputedConstructor
[95]    DirectConstructor    ::=    DirElemConstructor
| DirCommentConstructor
| DirPIConstructor
[96]    DirElemConstructor    ::=    "<" QName DirAttributeList ("/>" | (">" DirElemContent* "</" QName S? ">")) /* ws: explicitXQ */
[97]    DirAttributeList    ::=    (S (QName S? "=" S? DirAttributeValue)?)* /* ws: explicitXQ */
[98]    DirAttributeValue    ::=    ('"' (EscapeQuot | QuotAttrValueContent)* '"')
| ("'" (EscapeApos | AposAttrValueContent)* "'")
/* ws: explicitXQ */
[99]    QuotAttrValueContent    ::=    QuotAttrContentChar
| CommonContent
[100]    AposAttrValueContent    ::=    AposAttrContentChar
| CommonContent
[101]    DirElemContent    ::=    DirectConstructor
| CDataSection
| CommonContent
| ElementContentChar
[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
| CompElemConstructor
| CompAttrConstructor
| CompTextConstructor
| CompCommentConstructor
| CompPIConstructor
[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" "(" ")")
| (ItemType OccurrenceIndicator?)
[120]    OccurrenceIndicator    ::=    "?" | "*" | "+" /* gn: occurrence-indicatorsXQ */
[121]    ItemType    ::=    KindTest | ("item" "(" ")") | AtomicType
[122]    AtomicType    ::=    QName
[123]    KindTest    ::=    DocumentTest
| ElementTest
| AttributeTest
| SchemaElementTest
| SchemaAttributeTest
| PITest
| CommentTest
| TextTest
| AnyKindTest
[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")
| "after"
| "before") TargetExpr
[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

A.1 Terminal Symbols

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

B References

B.1 Normative References

XQuery Update Facility Requirements
World Wide Web Consortium. XQuery Update Facility Requirements. W3C Working Draft, 03 June 2005. See http://www.w3.org/TR/xquery-update-requirements.
XQuery/XPath Data Model (XDM)
World Wide Web Consortium. XQuery 1.0 and XPath 2.0 Data Model (XDM). W3C Working Draft, 03 November 2005. See http://www.w3.org/TR/xpath-datamodel/.
XQuery 1.0
World Wide Web Consortium. XQuery 1.0: An XML Query Language. W3C Working Draft, 03 November 2005. See http://www.w3.org/TR/xquery/.

B.2 Non-normative References

(None so far.)

C Error Conditions

err:XUST0101

It is a static error if an updating expression is used in any position other than one of the following:

  1. The do clause of a transform expression.

  2. The do clause of a FLWOR expression.

  3. The do clauses of a typeswitch expression in which every case clause and the default clause contain do clauses.

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

  5. An operand of a comma expression.

  6. The content of a parenthesized expression.

  7. The body of a function declaration in which the keyword updating is specified.

D Glossary (Non-Normative)

data model

The term data model refers to the data model specified by [XQuery/XPath Data Model (XDM)].

non-updating expression

A non-updating expression is an expression that cannot modify the state of an existing node.

pending update list

A pending update list is an unordered collection of update primitives, which represent node state changes that have not yet been applied.

remove-type

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.

replacement

A replacement is an operation that replaces a node or modifies the value of a node.

revalidation declaration

A revalidation declaration sets the revalidation mode in the static context, overriding any implementation-defined default.

revalidation mode

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

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.

snapshot semantics

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.

target node

The first argument of an update primitive, called its target node, is the principal node to be affected by the update primitive.

update operation

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 primitive

Each update primitive represents a node state change that has not yet been applied.

updating expression

An updating expression is an expression that can modify the state of an existing node.

XDM instance

The term XDM instance denotes an unconstrained sequence of zero or more nodes and/or atomic values as defined by the data model.

XQuery

Within this document, the term XQuery refers to the language specified by [XQuery 1.0].