W3C

XQuery Update Facility 1.0

W3C Recommendation 17 March 2011

This version:
http://www.w3.org/TR/2011/REC-xquery-update-10-20110317/
Latest version:
http://www.w3.org/TR/xquery-update-10/
Previous version:
http://www.w3.org/TR/2011/PR-xquery-update-10-20110125/
Editors:
Jonathan Robie, Red Hat <jonathan.robie@redhat.com>
Don Chamberlin, IBM Almaden Research Center
Michael Dyck <jmdyck@ibiblio.org>
Daniela Florescu, Oracle <dana.florescu@oracle.com>
Jim Melton, Oracle <jim.melton@oracle.com>
Jérôme Siméon, IBM T.J. Watson Research Center <simeon@us.ibm.com>

Please refer to the errata for this document, which may include some normative corrections.

See also translations.

This document is also available in these non-normative formats: XML and Recent revisions (HTML).


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 is a Recommendation of the W3C. It was developed by the W3C XML Query Working Group, which is part of the XML Activity.

This document incorporates minor changes made against the Proposed Recommendation of 25 January 2011. Changes to this document since the Proposed Recommendation are detailed in [H Revision Log]. A Java applet that parses XQuery Update Facility 1.0 expressions is available at http://www.w3.org/2010/02/qt-applets/xquery10-update/.

A Test Suite has been created for this document. Implementors are encouraged to run this test suite and report their results. The Test Suite can be found at http://dev.w3.org/2007/xquery-update-10-test-suite/. An implementation report is available at http://dev.w3.org/2007/xquery-update-10-test-suite/results/.

No substantive changes have been made to this specification since its publication as a Proposed Recommendation.

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

This document has been reviewed by W3C Members, by software developers, and by other W3C groups and interested parties, and is endorsed by the Director as a W3C Recommendation. It is a stable document and may be used as reference material or cited from another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment. This enhances the functionality and interoperability of the Web.

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

Table of Contents

1 Introduction
    1.1 Terminology
2 Extensions to XQuery 1.0
    2.1 Extensions to the Processing Model
    2.2 Extensions to the Prolog
        2.2.1 Revalidation Declaration
        2.2.2 Variable Declaration
        2.2.3 Function Declaration
    2.3 Extensions to the Static Context
    2.4 New Kinds of Expressions
        2.4.1 Insert
        2.4.2 Delete
        2.4.3 Replace
            2.4.3.1 Replacing a Node
            2.4.3.2 Replacing the Value of a Node
        2.4.4 Rename
        2.4.5 Transform
        2.4.6 Compatibility of Updating Expressions
    2.5 Extensions to Existing Expressions
        2.5.1 FLWOR Expression
        2.5.2 Typeswitch Expression
        2.5.3 Conditional Expression
        2.5.4 Comma Expression
        2.5.5 Parenthesized Expression
        2.5.6 Function Call
        2.5.7 Other Expressions
    2.6 Extensions to Built-in Function Library
        2.6.1 fn:put
3 Update Operations
    3.1 Update Primitives
        3.1.1 upd:insertBefore
        3.1.2 upd:insertAfter
        3.1.3 upd:insertInto
        3.1.4 upd:insertIntoAsFirst
        3.1.5 upd:insertIntoAsLast
        3.1.6 upd:insertAttributes
        3.1.7 upd:delete
        3.1.8 upd:replaceNode
        3.1.9 upd:replaceValue
        3.1.10 upd:replaceElementContent
        3.1.11 upd:rename
        3.1.12 upd:put
    3.2 Update Routines
        3.2.1 upd:mergeUpdates
        3.2.2 upd:applyUpdates
        3.2.3 upd:revalidate
        3.2.4 upd:removeType
        3.2.5 upd:setToUntyped
        3.2.6 upd:propagateNamespace
4 Static Typing Feature
    4.1 Overview and notations
    4.2 Change to Static Typing Rules of XQuery 1.0
    4.3 Core Grammar
    4.4 XQuery Update Facility 1.0 Prolog
    4.5 XQuery Update Facility 1.0 Expressions
        4.5.1 Insert
        4.5.2 Delete
        4.5.3 Replace
        4.5.4 Rename
        4.5.5 Transform
        4.5.6 Examples
5 Conformance
    5.1 Minimal Conformance
    5.2 Optional Features
        5.2.1 Update Facility Static Typing Feature
6 XQueryX Conformance

Appendices

A EBNF for XQuery 1.0 Grammar with Update extensions
    A.1 Terminal Symbols
B Implementation-Defined Items
C References
    C.1 Normative References
    C.2 Non-normative References
D Error Conditions
    D.1 New Error Codes
    D.2 Amendments to Existing Error Codes
E XML Syntax (XQueryX) for XQuery Update Facility 1.0
    E.1 Schema
    E.2 Stylesheet
    E.3 Example
        E.3.1 XQuery Representation
        E.3.2 XQueryX Representation
        E.3.3 Transformed XQuery Representation
F Glossary (Non-Normative)
G Rationale for Precedence of Update Primitives (Non-Normative)
H Revision Log (Non-Normative)


1 Introduction

This document defines the syntax and semantics of an extension to [XQuery 1.0] called the XQuery Update Facility 1.0. This language extension is designed to meet the requirements for updating instances of the [XQuery 1.0 and XPath 2.0 Data Model], as defined in [XQuery Update Facility 1.0 Requirements].

The XQuery Update Facility 1.0 provides facilities to perform any or all of the following operations on an XDM instance:

Additionally, this document defines an XML syntax for the XQuery Update Facility 1.0. The most recent versions of the two XQueryX XML Schemas and the XQueryX XSLT stylesheet for the XQuery Update Facility 1.0 are available at http://www.w3.org/2007/xquery-update-10/xquery-update-10-xqueryx.xsd, http://www.w3.org/2007/xquery-update-10/xquery-update-10-xqueryx-redef.xsd, and http://www.w3.org/2007/xquery-update-10/xquery-update-10-xqueryx.xsl, respectively.

1.1 Terminology

[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 1.0 and XPath 2.0 Data Model].] [Definition: The term XDM instance denotes an unconstrained sequence of zero or more nodes and/or atomic values as defined by the data model.] [Definition: The term node identity denotes the unique identity that is a property of every node in an XDM instance (see Section 2.3 Node IdentityDM.)]

As described in Section 3.3.3 QNames and NOTATIONSDM, names in XQuery are qualified names (QNames) that consist of an optional namespace prefix, a local name, and an optional namespace URI. [Definition: The implied namespace binding of a QName is the association of its namespace prefix (or absence thereof) with its namespace URI (or absence thereof).] [Definition: Two namespace bindings are said to conflict if their namespace prefixes (or absence thereof) are the same but their namespace URI's (or absence thereof) are different.] Update operations that result in conflicting namespace bindings generally raise errors, as described in this document. However, if the namespace prefix of an attribute is absent, it is in no namespace, and its implied namespace binding is not added to the namespace bindings of its parent element. Therefore, an update operation can create such an attribute in an element even though its implied namespace binding conflicts with a namespace binding in the "namespaces" property of the element.

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

Some of the examples in this document will be rejected by an implementation that supports the [4 Static Typing Feature].

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 zero 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 node identities.

XQuery Update Facility 1.0 introduces a new category of expression called an updating expression, which can potentially modify the state of an existing node.

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

  1. XQuery Update Facility 1.0 introduces five new kinds of expressions, called insert, delete, replace, rename, and transform expressions, and specifies the syntax and semantics of each new kind of expression.

  2. XQuery Update Facility 1.0 classifies XQuery expressions into the following categories:

    1. [Definition: A basic updating expression is an insert, delete, replace, or rename expression, or a call to an updating function.]

    2. [Definition: An updating expression is a basic updating expression or any expression (other than a transform expression) that directly contains an updating expression.]

      Note:

      The definition of an updating expression is recursive.

    3. [Definition: A simple expression is any XQuery expression that is not an updating expression.]

    4. [Definition: Certain expressions are defined in this specification to be vacuous expressions. These all have the characteristic that they can be determined statically to either return an empty sequence or raise an error.]

      Note:

      Every vacuous expression is identified explicitly in this specification. Some expressions can be determined to either return an empty sequence or raise an error, but are nevertheless not defined to be vacuous. For convenience, here is a list of the vacuous expressions:

      • A call to the built-in function fn:error is a vacuous expression.

      • An empty parenthesized expression ( ) is a vacuous expression.

      • A non-empty parenthesized expression is a vacuous expression if the expression it contains is a vacuous expression.

      • If all branches are vacuous expressions, the typeswitch expression is a vacuous expression.

      • If both branches are vacuous expressions, the conditional expression is a vacuous expression.

      • If all operands are vacuous expressions, the comma expression is a vacuous expression.

      • If the return clause of a FLWOR Expression is vacuous, the FLWOR expression is a vacuous expression.

  3. XQuery Update Facility 1.0 defines the places in which each type of expression can be used. In so doing, it makes small extensions to the syntax and semantics of certain existing expressions.

The classification of each expression into one of the above categories is performed by static analysis, according to rules specified in this document for each type of expression.

2.1 Extensions to the Processing Model

XQuery Update Facility 1.0 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 1.0 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.] The term "result" used in Section 2.3.4 Errors and OptimizationXQ includes both the XDM instance and the pending update list returned by an expression.

    Note:

    In XQuery Update Facility 1.0, no expression returns both a non-empty XDM instance and a non-empty pending update list.

  2. XQuery Update Facility 1.0 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 fall into the following categories:

    1. [Definition: Update primitives are the components of pending update lists. 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. [Definition: Update routines are sequences of actions that are used in the definition of XQuery semantics but do not appear on pending update lists.] upd:applyUpdates is an example of an update routine.

  3. If the outermost expression in a query returns a pending update list, upd:applyUpdates is implicitly invoked to apply the pending updates to the XDM instance. This invocation of upd:applyUpdates may raise an error (see [3.2.2 upd:applyUpdates] for possible error codes.)

[Definition: A snapshot is a scope within which expressions are evaluated with respect to a fixed XDM instance and updates are held pending.] A snapshot is terminated by invocation of the upd:applyUpdates operation. XQuery Update Facility 1.0 defines an entire query as one snapshot.

This specification defines the semantics of updates to an XDM instance. Propagation of these updates to an underlying persistent store (if any) is beyond the scope of this specification.

2.2 Extensions to the Prolog

2.2.1 Revalidation Declaration

[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:XUST0003]. Revalidation mode controls the process by which type information is recovered for an updated document, as described in [3.2.3 upd:revalidate]

Support for each of the three revalidation modes is implementation-defined; however, an implementation must support at least one of the three revalidation modes. If a revalidation declaration specifies a revalidation mode that is not supported by the current implementation, a static error is raised [err:XUST0026].

2.2.2 Variable Declaration

The following rule is added: If the expression on the right-hand-side of a variable declaration (the initializing expression) is not a simple expression, a static error is raised [err:XUST0001].

2.2.3 Function Declaration

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

The syntax of a function declaration is extended with an optional keyword: updating. [Definition: Functions whose declarations contain the keyword updating, and certain built-in functions including fn:put, are called updating functions.] The semantics of a function declaration, described in Section 4.15 of [XQuery 1.0], are extended as follows:

  1. If updating is not specified:

    1. If external is not specified, the EnclosedExpr in the function declaration must be a simple expression; otherwise a static error is raised [err:XUST0001].

    2. If external is specified, the external function must not return a non-empty pending update list; otherwise a dynamic error is raised [err:XUDY0018].

  2. If updating is specified:

    1. A return type must not be specified [err:XUST0028].

    2. If external is not specified, the EnclosedExpr in the function declaration must be an updating expression or a vacuous expression; otherwise a static error is raised [err:XUST0002].

    3. If external is specified, the external function may return a non-empty pending update list but it must not return a non-empty XDM instance; otherwise a dynamic error is raised [err:XUDY0019].

The means by which an external function returns an XDM instance or a pending update list is implementation-defined.

The following example illustrates a declaration of 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 xs:anyAtomicType) 
       {
       let $ea := $e/attribute()[fn:node-name(.) = $an]
       return
          if (fn:empty($ea))
          then insert node attribute {$an} {$av} into $e
          else replace value of node $ea with $av
       }
    

2.3 Extensions to the Static Context

  1. The following definition is added to the XQuery static context (documented in Section 2.1.1 Static ContextXQ):

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

  2. The following entry is added to the table of static context components (documented in Section C.1 Static Context ComponentsXQ):

    • Component: Revalidation mode

    • Default initial value: lax.

    • Can be overwritten by an implementation: Yes (implementation defined.)

    • Can be overwritten by a query: Yes, overwritable by declaration in query prolog.

    • Scope: Module.

    • Consistency rules: Must be strict, lax, or skip.

2.4 New Kinds of Expressions

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

XQuery Update Facility 1.0 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.

Note:

In general, updating expressions cause a loss of type information from nodes that are affected by the update. Type information for these nodes may be recovered by a revalidation process at the end of the snapshot. For more details on type loss and recovery, see the update primitives associated with each updating expression; see also [3.2.4 upd:removeType] and [3.2.3 upd:revalidate].

2.4.1 Insert

[143]    InsertExpr    ::=    "insert" ("node" | "nodes") SourceExpr InsertExprTargetChoice TargetExpr
[142]    InsertExprTargetChoice    ::=    (("as" ("first" | "last"))? "into")
| "after"
| "before"
[147]    SourceExpr    ::=    ExprSingle
[148]    TargetExpr    ::=    ExprSingle

An insert expression is an updating expression that inserts copies of zero or more nodes into a designated position with respect to a target node. The keywords node and nodes may be used interchangeably, regardless of how many nodes are actually inserted. The position of the inserted nodes is determined as follows:

  • If before (or after) is specified:

    • The inserted nodes become the preceding (or following) siblings of the target node.

    • If multiple nodes are inserted by a single insert expression, the nodes remain adjacent and their order preserves the node ordering of the source expression.

    • If multiple groups of nodes are inserted by multiple insert expressions in the same snapshot, adjacency and ordering of nodes within each group is preserved but ordering among the groups is implementation-dependent.

  • If as first into (or as last into) is specified:

    • The inserted nodes become the first (or last) children of the target node.

    • If multiple nodes are inserted by a single insert expression, the nodes remain adjacent and their order preserves the node ordering of the source expression.

    • If multiple groups of nodes are inserted by multiple insert expressions in the same snapshot, adjacency and ordering of nodes within each group is preserved but ordering among the groups is implementation-dependent.

  • If into is specified without as first or as last:

    • The inserted nodes become children of the target node.

    • If multiple nodes are inserted by a single insert expression, their order preserves the node ordering of the source expression.

    • The positions of the inserted nodes are chosen so as not to interfere with the intended position of nodes that are inserted with the specification before, after, as first into, or as last into. For example, If node B is inserted "after node A", no other node will be inserted between nodes A and B unless it is also inserted "after node A".

    • Subject to the above constraints, the positions of the inserted nodes among the children of the target node are implementation-dependent.

Examples:

  • Insert a year element after the publisher of the first book.

    insert node <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 node $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. SourceExpr must be a simple expression; otherwise a static error is raised [err:XUST0001]. SourceExpr is evaluated as though it were an enclosed expression in an element constructor (see Rule 1e in Section 3.7.1.3 ContentXQ). 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:XUTY0004]. 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.

    Note:

    Either $alist or $clist or both may be empty.

  2. The target expression must be a simple expression; otherwise a static error is raised [err:XUST0001]. The target expression is evaluated and checked as follows:

    1. If the result is an empty sequence, [err:XUDY0027] is raised.

    2. If any form of into is specified, the result must be a single element or document node; any other non-empty result raises a type error [err:XUTY0005].

    3. If before or after is specified, the result must be a single element, text, comment, or processing instruction node; any other non-empty result raises a type error [err:XUTY0006].

    4. If before or after is specified, the node returned by the target expression must have a non-empty parent property [err:XUDY0029].

    Let $target be the node returned by the target expression.

  3. If $alist is not empty and any form of into is specified, the following checks are performed:

    1. $target must be an element node [err:XUTY0022].

    2. No attribute node in $alist may have a QName whose implied namespace binding conflicts with a namespace binding in the "namespaces" property of $target [err:XUDY0023], unless the namespace prefix for the attribute is absent.

    3. Multiple attribute nodes in $alist must not have QNames whose implied namespace bindings conflict with each other [err:XUDY0024].

  4. If $alist is not empty and before or after is specified, the following checks are performed:

    1. parent($target) must be an element node [err:XUDY0030].

    2. No attribute node in $alist may have a QName whose implied namespace binding conflicts with a namespace binding in the "namespaces" property of parent($target) [err:XUDY0023] unless the namespace prefix for the attribute is absent.

    3. Multiple attribute nodes in $alist must not have QNames whose implied namespace bindings conflict with each other [err:XUDY0024].

  5. The result of the insert expression is an empty XDM instance and a pending update list constructed as follows:

    1. If as first into 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:insertIntoAsFirst($target, $clist)

    2. If as last into 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:insertIntoAsLast($target, $clist)

    3. If into is specified with neither as first nor as last, 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.4.2 Delete

[144]    DeleteExpr    ::=    "delete" ("node" | "nodes") TargetExpr
[148]    TargetExpr    ::=    ExprSingle

A delete expression deletes zero or more nodes from an XDM instance. The keywords node and nodes may be used interchangeably, regardless of how many nodes are actually deleted. A delete expression is an updating expression.

Examples:

  • Delete the last author of the first book in a given bibliography.

    delete node fn:doc("bib.xml")/books/book[1]/author[last()]
    
  • Delete all email messages that are more than 365 days old.

    delete nodes /email/message
         [fn:currentDate() - date > xs:dayTimeDuration("P365D")]
    

The semantics of a delete expression are as follows:

  1. The target expression must be a simple expression; otherwise a static error is raised [err:XUST0001]. The target expression is evaluated. The result must be a sequence of zero or more nodes; otherwise a type error is raised [err:XUTY0007]. Let $tlist be the list of nodes returned by the target expression.

  2. If any node in $tlist has no parent, it is removed from $tlist (and is thus ignored in the following step).

  3. 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 (together with an empty XDM instance) is the result of the delete expression.

Notes:

  • Since node deletions do not become effective until the end of a snapshot, they have no effect on variable bindings or on the set of available documents or collections within the current query.

  • The semantics of a delete expression are defined in terms of their effect on an XDM instance: the deleted nodes are detached from their parents after completion of the current query. The effects of a delete expression on persistent storage are beyond the scope of this specification.

2.4.3 Replace

[145]    ReplaceExpr    ::=    "replace" ("value" "of")? "node" TargetExpr "with" ExprSingle
[148]    TargetExpr    ::=    ExprSingle

A replace expression is an updating expression. A replace expression has two forms, depending on whether value of is specified.

2.4.3.1 Replacing a Node

If value of is not specified, a replace expression replaces one node with a new sequence of zero or more nodes. The replacement nodes occupy the position in the node hierarchy that was formerly occupied by the node that was replaced. For this reason, an attribute node can be replaced only by zero or more attribute nodes, and an element, text, comment, or processing instruction node can be replaced only by zero or more element, text, comment, or processing instruction nodes. Example:

  • Replace the publisher of the first book with the publisher of the second book.

    replace node 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 expression following the keyword with must be a simple expression; otherwise a static error is raised [err:XUST0001]. This expression is evaluated as though it were an enclosed expression in an element constructor (see Rule 1e in Section 3.7.1.3 ContentXQ). Let $rlist be the node sequence that results from this evaluation. If $rlist contains a document node, the document node is replaced in $rlist by its children.

  2. The target expression must be a simple expression; otherwise a static error is raised [err:XUST0001]. The target expression is evaluated and checked as follows:

    1. If the result is an empty sequence, [err:XUDY0027] is raised.

    2. If the result is non-empty and does not consist of a single element, attribute, text, comment, or processing instruction node, [err:XUTY0008] is raised.

    3. If the result consists of a node whose parent property is empty, [err:XUDY0009] is raised.

    Let $target be the node returned by the target expression, and let $parent be its parent node.

  3. If $target is an element, text, comment, or processing instruction node, then $rlist must consist exclusively of zero or more element, text, comment, or processing instruction nodes [err:XUTY0010].

  4. If $target is an attribute node, then:

    1. $rlist must consist exclusively of zero or more attribute nodes [err:XUTY0011].

    2. No attribute node in $rlist may have a QName whose implied namespace binding conflicts with a namespace binding in the "namespaces" property of $parent [err:XUDY0023] unless the namespace prefix for the attribute is absent.

    3. Multiple attribute nodes in $rlist must not have QNames whose implied namespace bindings conflict with each other [err:XUDY0024].

  5. The result of the replace expression is an empty XDM instance and a pending update list consisting of the following update primitive: upd:replaceNode($target, $rlist)

2.4.3.2 Replacing the Value of a Node

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 node 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 expression following the keyword with must be a simple expression; otherwise a static error is raised [err:XUST0001]. 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, in the absence of errors, is either a single text node or an empty sequence. Let $text be the result of this step.

  2. The target expression must be a simple expression; otherwise a static error is raised [err:XUST0001]. The target expression is evaluated and checked as follows:

    1. If the result is an empty sequence, [err:XUDY0027] is raised.

    2. If the result is non-empty and does not consist of a single element, attribute, text, comment, or processing instruction node, [err:XUTY0008] is raised.

    Let $target be the node returned by the target expression.

  3. If $target is an element node, the result of the replace expression is an empty XDM instance and a pending update list consisting of the following update primitive: upd:replaceElementContent($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. If Step 1 did not construct a text node, let $string be a zero-length string. Then:

    1. If $target is a comment node, and $string contains two adjacent hyphens or ends with a hyphen, a dynamic error is raised [err:XQDY0072].

    2. If $target is a processing instruction node, and $string contains the substring "?>", a dynamic error is raised [err:XQDY0026].

    3. In the absence of errors, the result of a replace expression is an empty XDM instance and a pending update list containing the following update primitive: upd:replaceValue($target, $string).

2.4.4 Rename

[146]    RenameExpr    ::=    "rename" "node" TargetExpr "as" NewNameExpr
[148]    TargetExpr    ::=    ExprSingle
[149]    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 node fn:doc("bib.xml")/books/book[1]/author[1]
    as "principal-author"
    
  • Rename the first author element of the first book to the QName that is the value of the variable $newname.

    rename node fn:doc("bib.xml")/books/book[1]/author[1]
    as $newname
    

The semantics of a rename expression are as follows:

  1. The target expression must be a simple expression; otherwise a static error is raised [err:XUST0001]. The target expression is evaluated and checked as follows:

    1. If the result is an empty sequence, [err:XUDY0027] is raised.

    2. If the result is non-empty and does not consist of a single element, attribute, or processing instruction node, [err:XUTY0012] is raised.

    Let $target be the node returned by the target expression.

  2. NewNameExpr must be a simple expression; otherwise a static error is raised [err:XUST0001]. NewNameExpr is processed as follows:

    1. If $target is an element node, let $QName be the result of evaluating NewNameExpr as though it were the name expression of a computed element constructor (see Section 3.7.3.1 Computed Element ConstructorsXQ). If the namespace binding of $QName conflicts with any namespace binding in the namespaces property of $target, a dynamic error is raised [err:XUDY0023].

    2. If $target is an attribute node, let $QName be the result of evaluating NewNameExpr as though it were the name expression of a computed attribute constructor (see Section 3.7.3.2 Computed Attribute ConstructorsXQ). If $QName has a non-absent namespace URI, and if the namespace binding of $QName conflicts with any namespace binding in the namespaces property of the parent (if any) of $target, a dynamic error is raised [err:XUDY0023].

    3. If $target is a processing instruction node, let $NCName be the result of evaluating NewNameExpr as though it were the name expression of a computed processing instruction constructor (see Section 3.7.3.5 Computed Processing Instruction ConstructorsXQ), and let $QName be defined as fn:QName((), $NCName).

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

Note:

The effects of a rename expression are limited to its target node. Attributes and descendants of the target node are not affected. If a global change of names or namespaces is intended, some form of explicit iteration must be used. The following example illustrates such a global change. The example operates on the node bound to variable $root and all its attributes and descendants, changing all QNames with the prefix abc to have a new prefix xyz and a new namespace URI http://xyz/ns.

for $node in $root//abc:*
let $localName := fn:local-name($node),
    $newQName := fn:concat("xyz:", $localName)
return (
   rename node $node as fn:QName("http://xyz/ns", $newQName),
   for $attr in $node/@abc:*
   let $attrLocalName := fn:local-name($attr),
       $attrNewQName := fn:concat("xyz:", $attrLocalName)
   return
      rename node $attr as fn:QName("http://xyz/ns", $attrNewQName)
)

2.4.5 Transform

[150]    TransformExpr    ::=    "copy" "$" VarName ":=" ExprSingle ("," "$" VarName ":=" ExprSingle)* "modify" 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 simple expression because it does not modify the value of any existing nodes.

Examples:

  • Return a sequence consisting of all employee elements that have Java as a skill, excluding their salary child-elements:

    for $e in //employee[skill = "Java"]
    return 
       copy $je := $e
       modify delete node $je/salary
       return $je
    
  • The following example copies a node, modifies the copy, and returns both the original node and the modified copy:

    let $oldx := /a/b/x
    return
       copy $newx := $oldx
       modify (rename node $newx as "newx", 
               replace value of node $newx with $newx * 2)
       return ($oldx, $newx)
    

    Note:

    No persistent changes to the underlying data result from this example.

A transform expression consists of three clauses, denoted by the keywords copy, modify, 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 be a simple expression; otherwise a static error is raised [err:XUST0001].

    2. The result of evaluating the source expression must be a single node [err:XUTY0013]. Let $node be this single node.

    3. A new copy is made of $node and all nodes that have $node as an ancestor, collectively referred to as copied nodes. Each copied node receives a new node identity. The parent, children, and attributes properties of the copied nodes are set so as to preserve their inter-node relationships. The parent property of the copy of $node is set to empty. Other properties of the copied nodes are determined as follows:

      1. For a copied element node, the type-name property is set to xs:untyped, and the nilled, is-id, and is-idrefs properties are set to false.

      2. For a copied attribute node, the type-name property is set to xs:untypedAtomic and the is-idrefs property is set to false. The is-id property is set to true if the qualified name of the attribute node is xml:id; otherwise it is set to false.

      3. The string value of each copied element and attribute node remains unchanged, and its typed value becomes equal to its string value as an instance of xs:untypedAtomic.

        Note:

        Implementations that store only the typed value of a node are required at this point to convert the typed value to a string form.

      4. If copy-namespaces mode in the static context specifies preserve, all in-scope-namespaces of the original element are retained in the new copy. If copy-namespaces mode specifies no-preserve, the new copy retains only those in-scope namespaces of the original element that are used in the names of the element and its attributes.

      5. All other properties of the copied nodes are preserved.

    4. The variable name is bound to the top-level copied node generated in the previous step. The scope of this variable binding includes all subexpressions of the containing transform expression that appear after the variable binding clause, including the source expressions of later variable bindings, but it does not include the source expression to which the current variable name is bound.

  2. The modify clause must contain an updating expression or a vacuous expression ; otherwise a static error is raised [err:XUST0002]. The expression in the modify 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:XUDY0014].

  3. Let $pul be the pending update list generated by the previous step. Let $revalidation-mode be the value of the revalidation mode in the static context of the transform expression. Let $inherit-namespaces be true if the copy-namespaces mode specifies inherit, or false if the copy-namespaces mode specifies no-inherit. The following update operation is invoked: upd:applyUpdates($pul, $revalidation-mode, $inherit-namespaces). The effect of this operation is to make the updates specified in the modify clause effective on the copied nodes.

    Note:

    In the event of incompatible updates, the upd:applyUpdates operation may raise an error, as described in [3.2.2 upd:applyUpdates].

  4. The return clause must contain a simple expression; otherwise a static error is raised [err:XUST0001]. 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.6 Compatibility of Updating Expressions

The rules defining compatibility of updating expressions within a snapshot are defined in [3.2.2 upd:applyUpdates].

Note:

The effect of these rules is as follows:

  1. If any node is affected by more than one rename expression within a snapshot, a dynamic error is raised [err:XUDY0015].

  2. If any node is affected by more than one replace expression (without value of being specified) within a snapshot, a dynamic error is raised [err:XUDY0016].

  3. If any node is affected by more than one replace value of expression within a snapshot, a dynamic error is raised [err:XUDY0017].

  4. If multiple calls to fn:put operate on the same URI in the same snapshot, a dynamic error is raised [err:XUDY0031].

  5. Within a given snapshot, if an element node E is the target of a replace value of expression, and the children of E are also modified by other expressions, the final children of E are determined by the replace value of expression. For example:

    • Suppose that $A is bound to an element node that has a child element named B. Suppose that the following expressions are evaluated in the same snapshot:

      replace node $A/B with <C>Hello</C>,
      replace value of node $A with <D>Goodbye</D>
      

      The expressions on the left and right side of the comma can be evaluated in any order. No error is raised. At the end of the snapshot, the children of $A will consist of a single text node with the content "Goodbye".

2.5 Extensions to Existing Expressions

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

2.5.1 FLWOR Expression

The syntax of the FLWOR expression is not changed. Its semantics are extended as follows:

  1. If a for, let, where, or order by clause contains an updating expression, a static error is raised [err:XUST0001].

  2. The return clause may contain any category of expression. The category of the FLWOR expression is the same as the category of the expression in its return clause (simple, vacuous, or updating.)

  3. If the return clause contains a simple expression, the semantics of the FLWOR expression are as specified in Section 3.8 FLWOR ExpressionsXQ.

  4. If the return clause contains an updating expression, the semantics of the FLWOR expression are as follows:

    1. The semantics of the for, let, where, and order by clauses are as specified in Section 3.8 FLWOR ExpressionsXQ. These clauses generate a stream of tuples of bound variables.

    2. For each tuple generated by the previous step, the updating expression in the return clause is evaluated, resulting in a pending update list.

    3. All the pending update lists generated by the previous step are merged by successive invocations of the upd:mergeUpdates operation. The resulting merged pending update list is the result of the FLWOR expression.

      Note:

      In the event of incompatible updates, the upd:mergeUpdates operation may raise an error, as described in [3.2.1 upd:mergeUpdates].

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]
    return 
        replace value of node $p/quantity
        with $p/quantity + $deltap/quantity
    

2.5.2 Typeswitch Expression

The syntax of the typeswitch expression is not changed. Its semantics are extended as follows. Let the expressions in the case and default clauses be called branches. Then:

  1. If the operand expression of a typeswitch is an updating expression, a static error is raised [err:XUST0001].

  2. If any branch is an updating expression, then all branches must be updating or vacuous expressions [err:XUST0001]. In this case, the typeswitch expression is an updating expression.

  3. If all branches are vacuous expressions, the typeswitch expression is a vacuous expression.

  4. Otherwise, the typeswitch expression is a simple expression.

  5. If the typeswitch expression is a simple (including vacuous) expression, its semantics are as specified in Section 3.12.2 TypeswitchXQ.

  6. If the typeswitch expression is an updating expression, then selection of the effective case and binding of variables are performed as specified in Section 3.12.2 TypeswitchXQ. The expression in the return clause of the effective case (or default) is then evaluated, resulting in a pending update list, which serves as the result of the typeswitch expression.

2.5.3 Conditional Expression

The semantics of conditional expressions are extended as follows. Let the expressions in the then and else clauses be called branches. Then:

  1. If the if-clause contains an updating expression, a static error is raised [err:XUST0001].

  2. If either branch is an updating expression, then both branches must be updating or vacuous expressions [err:XUST0001]. In this case, the conditional expression is an updating expression.

  3. If both branches are vacuous expressions, the conditional expression is a vacuous expression.

  4. Otherwise, the conditional expression is a simple expression.

  5. If the conditional expression is a simple (including vacuous) expression, its semantics are as specified in Section 3.10 Conditional ExpressionsXQ.

  6. If the conditional expression is an updating expression, then selection of the effective branch performed as specified in Section 3.10 Conditional ExpressionsXQ. The result of the conditional expression is the pending update list 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 node 
            $e/last-updated with fn:currentDate()
    else insert node 
            attribute last-updated {fn:currentDate()} into $e
    

2.5.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 Constructing SequencesXQ) are extended as follows:

  1. If any operand is an updating expression, then all operands must be updating or vacuous expressions [err:XUST0001]. In this case, the comma expression is an updating expression.

  2. If all operands are vacuous expressions, the comma expression is a vacuous expression.

  3. Otherwise, the comma expression is a simple expression.

  4. If the comma expression is a simple (including vacuous) expression, its semantics are as specified in Section 3.3.1 Constructing SequencesXQ.

  5. If the comma expression is an updating expression, its operand expressions are evaluated (in any order), and the pending update lists returned by the operand expressions are merged by the upd:mergeUpdates operation. The resulting merged pending update list is the result of the comma expression.

The following example illustrates the use of an updating comma expression:

  • 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
    return
       ( replace value of node $q with ( ),
         insert node attribute xsi:nil {"true"} into $q )
    

2.5.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 the expression enclosed in parentheses, which may have any category. The result of a parenthesized expression is also the same as the result of the expression enclosed in parentheses.

An empty parenthesized expression ( ) is a vacuous expression. Its result is an empty sequence and an empty pending update list.

2.5.6 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:XUST0001].

The expression category of a function call is as follows:

2.5.7 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:XUST0001].

2.6 Extensions to Built-in Function Library

XQuery Update Facility 1.0 provides extensions to XQuery built-in function library, as specified in this section.

2.6.1 fn:put

fn:put($node as node(), $uri as xs:string) as empty-sequence()

Summary: Stores a document or element to the location specified by $uri. This function is normally invoked to create a resource on an external storage system such as a file system or a database.

The external effects of fn:put are implementation-defined, since they occur outside the domain of XQuery. The intent is that, if fn:put is invoked on a document node and no error is raised, a subsequent query can access the stored document by invoking fn:doc with the same URI.

Semantics:

  1. fn:put is an updating function.

  2. If $node is not a document node or an element node, and the implementation does not support fn:put on the given node kind, a dynamic error is raised [err:FOUP0001].

  3. If $uri is not a valid lexical representation of the xs:anyURI type, a dynamic error is raised [err:FOUP0002]. If $uri is a relative URI reference, it is resolved relative to the value of the base URI property in the static context.

  4. The result of a call to fn:put is an empty XDM instance and a pending update list containing the following update primitive: upd:put($node, $uri).

Notes:

  • The results of fn:put do not become effective until after completion of the current snapshot. The fn:put function has no effect on the set of available documents or collections seen by the current snapshot.

  • If a node that is an operand of fn:put is affected by updating expressions in the current snapshot, the fn:put function operates on the node after these updating expressions are made effective. As a result, after completion of the current snapshot, the effects of updates to $node can be seen via $uri. (For details on application of updates, see [3.2.2 upd:applyUpdates].)

  • If multiple calls to fn:put in the same snapshot operate on the same URI (after any necessary resolution of relative URIs), a dynamic error [err:XUDY0031] is raised. The dynamic error is raised by an expression at some level of the query that contains more than one call to fn:put. For a normative description of this error, see [3.2.1 upd:mergeUpdates] and [3.2.2 upd:applyUpdates].

3 Update Operations

This section describes the update operations defined by XQuery Update Facility 1.0. 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.

Update operations consist of update primitives, which are the components of pending update lists, and update routines, which are used in defining XQuery semantics but do not appear on pending update lists.

3.1 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 their node identities. The semantics of an update primitive do not become effective until their pending update list is processed by the upd:applyUpdates routine.

3.1.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 xs:untyped, then upd:setToUntyped() is invoked on 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 at least one of the nodes in $content is an element or text node, upd:removeType(parent($target)) is invoked.

  3. All the namespace bindings of parent($target) are marked for namespace propagation.

3.1.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.1.3 upd:insertInto

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

Inserts $content as the children of $target, in an implementation-dependent 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:insertInto are identical to the semantics of upd:insertBefore, except that $target is substituted everywhere for parent($target), and Rule 2a is changed as follows:

  • The children property of $target is changed to add the nodes in $content in implementation-dependent positions, preserving their relative order.

3.1.4 upd:insertIntoAsFirst

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

Inserts $content as the first 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:insertIntoAsFirst are identical to the semantics of upd:insertBefore, except that $target is substituted everywhere for parent($target), and Rule 2a is changed as follows:

  • The children property of $target is changed to add the nodes in $content as the first children, preserving their order.

3.1.5 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 substituted everywhere for parent($target), and Rule 2a is changed as follows:

  • The children property of $target is changed to add the nodes in $content as the last children, preserving their order.

3.1.6 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 xs:untyped, then upd:setToUntyped($A) is invoked.

  2. The following properties of $target are changed:

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

    2. namespaces: Modified to add namespace bindings for any attribute namespace prefixes in $content that did not already have bindings. These bindings are marked for namespace propagation.

    3. upd:removeType($target) is invoked.

3.1.7 upd:delete

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

None

Semantics
  1. If $target has a parent node $P, then:

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

    2. If $target is an attribute node, the attributes property of $P is modified to remove $target.

    3. If $target is a non-attribute node, the children property of $P is modified to remove $target.

    4. If $target is an element, attribute, or text node, and $P is an element node, then upd:removeType($P) is invoked.

  2. If $target has no parent, the XDM instance is unchanged.

Note:

Deleted nodes are detached from their parent nodes; however, a node deletion has no effect on variable bindings or on the set of available documents or collections during processing of the current query.

Note:

Multiple upd:delete operations may be applied to the same node during execution of a query; this is not an error.

3.1.8 upd:replaceNode

Parameters
upd:replaceNode(
   $target as node(),
   $replacement as node()*)
Summary

Replaces $target with $replacement.

Constraints

$target must be a node that has a parent. If $target is an attribute node, $replacement must consist of zero or more attribute nodes. If $target is an element, text, comment, or processing instruction node, $replacement must be consist of zero or more element, text, comment, or processing instruction nodes.

Semantics
  1. Effects on nodes in $replacement:

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

    2. If the type-name property of parent($target) is xs:untyped, then upd:setToUntyped() is invoked on each node in $replacement.

  2. Effect on $target:

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

  3. Effects on parent($target):

    1. If $target is an attribute node, the attributes property of parent($target) is modified by removing $target and adding the nodes in $replacement (if any).

    2. If $target is an attribute node, the namespaces property of parent($target) is modified to add namespace bindings for any attribute namespace prefixes in $replacement that did not already have bindings. These bindings are marked for namespace propagation.

    3. If $target is an element, text, comment, or processing instruction node, the children property of parent($target) is modified by removing $target and adding the nodes in $replacement (if any) in the former position of $target, preserving their order.

    4. If $target or any node in $replacement is an element, attribute, or text node, upd:removeType(parent($target)) is invoked.

3.1.9 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. upd:removeType($target) is invoked.

  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 that has a parent, upd:removeType(parent($target)) is invoked.

3.1.10 upd:replaceElementContent

Parameters
upd:replaceElementContent(
   $target as element(),
   $text as text()?)
Summary

Replaces the existing children of the element node $target by the optional text node $text. The attributes of $target are not affected.

Constraints

None.

Semantics
  1. For each node $C that is a child of $target, the parent property of $C is set to empty.

  2. The parent property of $text is set to $target.

  3. Effects on $target:

    1. children is set to consist exclusively of $text. If $text is an empty sequence, then $target has no children.

    2. typed-value and string-value are set to the content property of $text. If $text is an empty sequence, then typed-value is an empty sequence and string-value is an empty string.

    3. upd:removeType($target) is invoked.

3.1.11 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. upd:removeType($target) is invoked.

    3. If $newname has no prefix and no namespace URI, the namespaces property of $target is modified by removing the binding (if any) for the empty prefix.

    4. The namespaces property of $target is modified to add a namespace binding derived from $newName, if this binding did not already exist. This binding is marked for namespace propagation.

  2. If $target is an attribute node:

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

    2. upd:removeType($target) is invoked.

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

    4. If $target has a parent, the namespaces property of parent($target) is modified to add a namespace binding derived from $newName, if this binding did not already exist. This binding is marked for namespace propagation.

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

Note:

At the end of a snapshot, if multiple attribute nodes with the same parent have the same qualified name, an error will be raised by upd:applyUpdates.

3.1.12 upd:put

Parameters
upd:put(
   $node as node(),
   $uri as xs:string)
Summary

The XDM node tree rooted at $node is stored to the location specified by $uri.

Constraints

$uri must be a valid absolute URI.

Semantics

The external effects of upd:put are implementation-defined, since they occur outside the domain of XQuery. The intent is that, if upd:put is invoked on a document node and no error is raised, a subsequent query can access the stored document by invoking fn:doc with the same URI.

3.2 Update Routines

3.2.1 upd:mergeUpdates

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

Merges two pending update lists.

Constraints

None.

Semantics
  1. The two pending update lists are merged and a single pending update list containing all the update primitives from both lists is returned.

  2. Optionally, upd:mergeUpdates may raise a dynamic error if any of the following conditions are detected:

    1. Two or more upd:rename primitives on the merged list have the same target node [err:XUDY0015].

    2. Two or more upd:replaceNode primitives on the merged list have the same target node [err:XUDY0016].

    3. Two or more upd:replaceValue primitives on the merged list have the same target node [err:XUDY0017].

    4. Two or more upd:replaceElementContent primitives on the merged list have the same target node [err:XUDY0017].

    5. Two or more upd:put primitives on the merged list have the same $uri operand [err:XUDY0031].

    6. Two or more primitives on the merged list create conflicting namespace bindings for the same element node [err:XUDY0024]. The following kinds of primitives create namespace bindings:

      1. upd:insertAttributes creates one namespace binding on the $target element corresponding to the implied namespace binding of the name of each attribute node in $content if the name has a non-empty prefix.

      2. upd:replaceNode creates one namespace binding on the parent($target) element corresponding to the implied namespace binding of the name of each attribute node in $replacement if the name has a non-empty prefix.

      3. upd:rename creates a namespace binding on $target, or on the parent (if any) of $target if $target is an attribute node, corresponding to the implied namespace binding of $newName. However, if $target is an attribute and its name has an empty prefix, the namespace binding is not created.

3.2.2 upd:applyUpdates

Parameters
upd:applyUpdates(
   $pul as pending-update-list,
   $revalidation-mode as xs:string,
   $inherit-namespaces as xs:boolean)
Summary

This routine ends a snapshot by making effective the semantics of all the update primitives on a pending update list and by revalidating the resulting XDM instance.

Constraints

$revalidation-mode must be "strict", "lax", or "skip"

Semantics
  1. Checks the update primitives on $pul for compatibility. Raises a dynamic error if any of the following conditions are detected:

    1. Two or more upd:rename primitives on $pul have the same target node [err:XUDY0015].

    2. Two or more upd:replaceNode primitives on $pul have the same target node [err:XUDY0016].

    3. Two or more upd:replaceValue primitives on $pul have the same target node [err:XUDY0017].

    4. Two or more upd:replaceElementContent primitives on $pul have the same target node [err:XUDY0017].

    5. Two or more upd:put primitives on the merged list have the same $uri operand [err:XUDY0031].

    6. Two or more primitives on $pul create conflicting namespace bindings for the same element node [err:XUDY0024]. The following kinds of primitives create namespace bindings:

      1. upd:insertAttributes creates one namespace binding on the parent($target) element corresponding to the implied namespace binding of the name of each attribute node in $content if the name has a non-empty prefix.

      2. upd:replaceNode creates one namespace binding on the $target element corresponding to the implied namespace binding of the name of each attribute node in $replacement if the name has a non-empty prefix.

      3. upd:rename creates a namespace binding on $target, or on the parent (if any) of $target if $target is an attribute node, corresponding to the implied namespace binding of $newName. However, if $target is an attribute and its name has an empty prefix, the namespace binding is not created.

  2. The semantics of all update primitives on $pul, other than upd:put primitives, are made effective in the following order:

    1. First, all upd:insertInto, upd:insertAttributes, upd:replaceValue, and upd:rename primitives are applied.

    2. Next, all upd:insertBefore, upd:insertAfter, upd:insertIntoAsFirst, and upd:insertIntoAsLast primitives are applied.

    3. Next, all upd:replaceNode primitives are applied.

    4. Next, all upd:replaceElementContent primitives are applied.

    5. Next, all upd:delete primitives are applied.

  3. If, as a net result of the above steps, the children property of some node 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 node identity of the resulting text node is implementation-dependent.

  4. If, as a net result of the above steps, the children property of some node contains an empty text node, that empty text node is deleted from the children property.

  5. If, after applying the updates, any XDM instance (including a node that has been deleted or detached from its parent, or that is a descendant of such a node) violates any constraint specified in [XQuery 1.0 and XPath 2.0 Data Model], a dynamic error is raised [err:XUDY0021].

    Note:

    For example, a data model constraint violation might occur if multiple attributes with the same parent have the same qualified name (see Section 6.2.1 OverviewDM.)

    Note:

    During processing of a pending update list, an XDM instance may temporarily violate a data model constraint. An error is raised only if a constraint remains unsatisfied after all update primitives other than upd:put have been applied.

  6. If $inherit-namespaces is true, then upd:propagateNamespace($element, $prefix, $uri) is invoked for each namespace binding that was marked for namespace propagation, except for namespace bindings associated with the empty prefix, where $element is the element node on which the namespace binding appears, $prefix is the namespace prefix, and $uri is the namespace URI. Each of these nodes is then unmarked.

  7. For each document or element node $top that was marked for revalidation by one of the earlier steps, upd:revalidate($top, $revalidation-mode) is invoked. Each of these nodes is then unmarked.

  8. As the final step, all upd:put primitives on $pul are applied.

  9. The upd:applyUpdates operation is atomic with respect to the data model. In other words, if upd:applyUpdates terminates normally, the resulting XDM instance reflects the result of all update primitives; but if upd:applyUpdates raises an error, the resulting XDM instance reflects no changes. Atomicity is guaranteed only with respect to operations on XDM instances, and only with respect to error conditions specified in this document.

    Note:

    The results of implementation-dependent error conditions such as exceeding resource limits are beyond the scope of this specification.

  10. Propagation of XDM changes to an underlying persistent store is beyond the scope of this specification. For example, the effect on persistent storage of deleting a node that has no parent is beyond the scope of this specification.

3.2.3 upd:revalidate

Parameters
upd:revalidate(
   $top as node(),
   $revalidation-mode as xs:string)
Constraints

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

$revalidation-mode must be "strict", "lax", or "skip".

Summary

Schema validation is applied to the subtree rooted at $top in order to recover the types of updated nodes while preserving their node identities.

Semantics

If $revalidation-mode is skip, upd:revalidate performs no action. Otherwise:

  1. If $revalidation-mode is lax, define $topV as the result of the XQuery expression validate lax {$top}. If $revalidation-mode is strict, define $topV as the result of the XQuery expression validate strict {$top}. During computation of $topV, it is necessary to maintain a mapping between each node in $topV and the corresponding node (if any) in the subtree rooted at $top (this mapping is maintained in an implementation-dependent way.)

    Note:

    • This step may raise an error [err:XQDY0027]XQ if $top is found to be invalid.

    • Some of the nodes in $topV (for example, default attributes generated by the validation process) may have no corresponding nodes in $top.

  2. For each node $nV in $topV that has a corresponding node $n in $top, replace the following properties of $n with the corresponding properties of $nV: type-name, typed-value, string-value, is-id, is-idrefs, namespace-bindings, nilled.

  3. For each node $nV in $topV that does not have a corresponding node in $top, insert the node $nV into the subtree rooted at $top as a child or attribute of the node corresponding to the parent of $nV.

  4. The result of upd:revalidate is to modify the properties of the nodes rooted at $top and possibly to add some new nodes to this subtree. When the revalidation process is complete, $topV can be discarded.

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.2.4 upd:removeType

Parameters
upd:removeType(
   $N as node())
Constraints

$N must be an element or attribute node

Summary

This routine is applied to a node whose name or content has been modified, in order to remove specific type information from the node and its ancestors, pending revalidation.

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

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

      1. type-name is set to xs:anyType

      2. If the parent of N is an element node, then upd:removeType(parent($N)) is invoked.

    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 xs: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 xs:untypedAtomic.

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

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

    4. If $N has a parent, upd:removeType(parent($N)) is invoked.

  3. The topmost ancestor of $N is marked for revalidation.

    [Definition: To mark a node means to identify the node as participating in a later operation.] Marking of nodes is accomplished in an implementation-dependent way--for example, an implementation might maintain a list of marked nodes.

3.2.5 upd:setToUntyped

Parameters
upd:setToUntyped(
   $N as node())
Constraints

$N must be an element or attribute node

Summary

This routine is applied to a node that has been inserted into an untyped context, which requires that the node and its descendants be untyped as well.

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

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

    2. typed-value is set equal to the string-value property, as an instance of xs: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. upd:setToUntyped() 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 xs:untypedAtomic.

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

    3. is-idrefs is set to false.

    4. is-id is set to false if the attribute name is not xml:id.

3.2.6 upd:propagateNamespace

Parameters
upd:propagateNamespace(
   $element as element(), 
   $prefix as xs:NCName, 
   $uri as xs:anyURI)
Constraints

None

Summary

Propagates a namespace binding to all descendants of an element.

Semantics

For each element $child among the children of $element that does not have a namespace binding for $prefix,

  1. add a namespace binding ($prefix, $uri) to $child

  2. call upd:propagateNamespace($child, $prefix, $uri)

4 Static Typing Feature

XQuery 1.0 includes an optional static typing feature. This section describes the static typing feature for the XQuery Update Facility 1.0. Implementations of this specification that support optional static typing must implement the following static typing rules, along with the XQuery 1.0 static typing rules defined in [XQuery 1.0 and XPath 2.0 Formal Semantics].

4.1 Overview and notations

The concepts and notations used in this specification are the same as those used to define the static typing feature for XQuery 1.0. For convenience, we recall here some of the main concepts and notations. We refer the reader to [XQuery 1.0 and XPath 2.0 Formal Semantics] for a more detailed introduction.

The static typing feature for the XQuery Update Facility 1.0 is defined based on a processing model similar to the one of XQuery 1.0. We first define the XQuery Update Facility 1.0 Core, as a subset of the XQuery Update Facility 1.0. Then for each kind of updating expression, we give the normalization rules from the XQuery Update Facility 1.0 into that Core, as well as the inference rules that compute the type for each Core expression.

Notation

Normalization rules map expressions in the XQuery Update Facility 1.0 into expressions in the XQuery Update Facility 1.0 Core. They are written as follows.

 
[Expr]Expr
==
CoreExpr

Notation

The static semantics is specified through a judgment which gives for each expression its corresponding static type. The meaning of that judgment is defined through inference rules as in [XQuery 1.0 and XPath 2.0 Formal Semantics].

The judgment

statEnv |- Expr : Type

holds when, in the static environment statEnv, the expression Expr has type Type.

Notation

The static environment is the same as the one defined in [XQuery 1.0 and XPath 2.0 Formal Semantics], extended with an entry corresponding to the revalidation mode, as follows.

statEnv.revalidationMode
The statEnv.revalidationMode environment component designates the revalidation mode in the XQuery Update Facility 1.0 static context.
The statEnv.revalidationMode environment component is one of strict, lax, or skip.

4.2 Change to Static Typing Rules of XQuery 1.0

XQuery 1.0 specifies that err:XPST0005 is raised if the Static Typing Feature is in effect and the static type assigned to an expression other than ( ) or data(( )) is empty-sequence( ). XQuery Update Facility 1.0 modifies this rule so that it applies only to simple expressions (i.e., it does not apply to updating expressions.)

4.3 Core Grammar

We extend the XQuery Core defined in [XQuery 1.0 and XPath 2.0 Formal Semantics] with five expressions needed to support the XQuery Update Facility 1.0: insert, delete, rename, replace, and transform.

[23 (Core)]    ExprSingle    ::=    FLWORExpr
| QuantifiedExpr
| TypeswitchExpr
| IfExpr
| InsertExpr
| DeleteExpr
| RenameExpr
| ReplaceExpr
| TransformExpr
| OrExpr
[99 (Core)]    InsertExpr    ::=    "insert" "nodes" SourceExpr InsertExprTargetChoice TargetExpr
[98 (Core)]    InsertExprTargetChoice    ::=    (("as" ("first" | "last"))? "into")
| "after"
| "before"
[103 (Core)]    SourceExpr    ::=    ExprSingle
[104 (Core)]    TargetExpr    ::=    ExprSingle
[100 (Core)]    DeleteExpr    ::=    "delete" "nodes" TargetExpr
[101 (Core)]    ReplaceExpr    ::=    "replace" ("value" "of")? "node" TargetExpr "with" ExprSingle
[102 (Core)]    RenameExpr    ::=    "rename" "node" TargetExpr "as" NewNameExpr
[105 (Core)]    NewNameExpr    ::=    ExprSingle
[106 (Core)]    TransformExpr    ::=    "copy" "$" VarName ":=" ExprSingle ("," "$" VarName ":=" ExprSingle)* "modify" ExprSingle "return" ExprSingle

4.4 XQuery Update Facility 1.0 Prolog

In addition to the normalization rules defined in [XQuery 1.0 and XPath 2.0 Formal Semantics] for the XQuery 1.0 prolog, the following normalization rules apply to the revalidation mode setter.

Normalization

Revalidation declarations are left unchanged through normalization.

 
[RevalidationDecl]PrologDecl
==
RevalidationDecl

Static Context Processing

The revalidation declaration modifies the revalidation mode in the static context.

statEnv1 = statEnv + revalidationMode( RevalidationMode)

statEnv |- declare revalidation RevalidationMode =>stat statEnv1

4.5 XQuery Update Facility 1.0 Expressions

In addition to the normalization and static typing rules defined in [XQuery 1.0 and XPath 2.0 Formal Semantics] for XQuery 1.0 expressions, the normalization and static typing rules described in this specification apply to the expressions in the XQuery Update Facility 1.0. For each expression except the transform expression, the final type is the empty type which corresponds to the value being returned. In each case, the static typing rules check that every sub-expression is well-typed, and that the resulting value is consistent with the constraints specific to each expression. For instance, the expression used in a delete must return a sequence of nodes.

4.5.1 Insert

Normalization

The following normalization rules apply to insert expressions. Note that whether the expression is written using the 'nodes' or 'node' modifier, the normalized expression always uses the 'nodes' modifier.

 
[insert (node|nodes) Expr1 InsertExprTargetChoice Expr2]Expr
==
insert nodes fs:item-sequence-to-node-sequence([Expr1]Expr) InsertExprTargetChoice [Expr2]Expr

Where fs:item-sequence-to-node-sequence is the special function used for computing element content and is defined in [XQuery 1.0 and XPath 2.0 Formal Semantics].

Static Type Analysis

The static typing rule for insert depends on whether it is an insert into, or an insert before or after.

In the case of an insert into, the inference depends on whether the target node is an element or a document node (in which case it does not allow attribute nodes to be inserted). This is expressed by the two following rules.

statEnv  |- Expr1 : Type1
statEnv |- Type1 <: (attribute *)*, (element * | text | comment | processing-instruction *)*
statEnv  |- Expr2 : Type2
statEnv |- Type2 <: (element *)?

statEnv  |- insert nodes Expr1 ((as (first | last))? into) Expr2 : empty

statEnv  |- Expr1 : Type1
statEnv |- Type1 <: (element * | text | comment | processing-instruction *)*
statEnv  |- Expr2 : Type2
statEnv |- Type2 <: [document-node()?]sequencetype

statEnv  |- insert nodes Expr1 ((as (first | last))? into) Expr2 : empty

In the case of an insert before or after, the type of the target node must be either an element, text, comment or processing-instruction node. This is expressed by the following rule.

statEnv  |- Expr1 : Type1
statEnv |- Type1 <: (attribute *)*, (element * | text | comment | processing-instruction *)*
statEnv  |- Expr2 : Type2
statEnv |- Type2 <: (element * | text | comment | processing-instruction *)?

statEnv  |- insert nodes Expr1 (after | before) Expr2 : empty

4.5.2 Delete

Normalization

The following normalization rule applies to delete expressions. Note that whether the expression is written using the 'nodes' or 'node' modifier, the normalized expression always uses the 'nodes' modifier.

 
[delete (node|nodes) Expr1]Expr
==
delete nodes [Expr1]Expr

Static Type Analysis

The static typing rule for delete is as follows.

statEnv  |- Expr : Type
statEnv |- Type <: [node()*]sequencetype

statEnv  |- delete (node|nodes) Expr : empty

4.5.3 Replace

Normalization

The following normalization rules applies to replace expressions.

 
[replace node Expr1 with Expr2]Expr
==
replace node [Expr1]Expr with fs:item-sequence-to-node-sequence([Expr2]Expr)

Normalization of replace value of expressions.

 
[replace value of node Expr1 with Expr2]Expr
==
replace value of node [Expr1]Expr with [text { Expr2 }]Expr

Static Type Analysis

If the value of modifier is not specified, a replace expression replaces one node with a new sequence of zero or more nodes.

An attribute node can be replaced only by zero or more attribute nodes.

statEnv  |- Expr1 : Type1
statEnv |- Type1 <: (attribute *)?
statEnv  |- Expr2 : Type2
statEnv |- Type2 <: (attribute *)*

statEnv  |- replace node Expr1 with Expr2 : empty

An element, text, comment, or processing instruction node can be replaced only by zero or more element, text, comment, or processing instruction nodes.

statEnv  |- Expr1 : Type1
statEnv |- Type1 <: (element * | text | comment | processing-instruction *)?
statEnv  |- Expr2 : Type2
statEnv |- Type2 <: (element * | text | comment | processing-instruction *)*

statEnv  |- replace node Expr1 with Expr2 : empty

If the value of modifier is specified, a replace expression replaces the content of a single node, which must not be a document node by either a single text node or empty.

statEnv  |- Expr1 : Type1
statEnv |- Type1 <: (attribute *| element * | text | comment | processing-instruction *)?
statEnv  |- Expr2 : Type2
statEnv |- Type2 <: text?

statEnv  |- replace value of node Expr1 with Expr2 : empty

4.5.4 Rename

Normalization

The following normalization rule applies to rename expressions.

 
[rename node Expr1 as Expr2]Expr
==
rename node [Expr1]Expr as fn:data([Expr2]Expr)

Static Type Analysis

The target of a rename expression must be either an element, attribute or processing-instruction, and its new name must be either of type xs:QName, xs:string, or xs:untypedAtomic.

statEnv  |- Expr1 : Type1
statEnv |- Type1 <: (attribute *| element * | processing-instruction *)?
statEnv  |- Expr2 : Type2
statEnv |- Type2 <: (xs:QName | xs:string | xs:untypedAtomic)

statEnv  |- rename node Expr1 as Expr2 : empty

4.5.5 Transform

Normalization

The following normalization rule applies to transform expressions.

 
[
copy
  VarName1 := Expr1
    ...
  VarNamen := Exprn
  modify Expr0 return Exprr
]Expr
==
copy
  VarName1 := [Expr1]Expr
    ...
  VarNamen := [Exprn]Expr
  modify [Expr0]Expr return [Exprr]Expr

Static Type Analysis

The transform expression is type checked using the following inference rule.

statEnv  |- Expr1 : Type1
statEnv |-  Type1 <: [node()]sequencetype
statEnv |- VarName1 of var expands to Variable1
statEnv1 = statEnv + varType(Variable1 => [node()]sequencetype)
...
statEnvn-1 |-  Exprn : Typen
statEnvn-1 |-  Typen <: [node()]sequencetype
statEnv |- VarNamen of var expands to Variablen
statEnvn = statEnvn-1 + varType(Variablen => [node()]sequencetype)
statEnvn |-  Expr0 : Type0
statEnvn |-  Exprr : Typer

statEnv  |- 
copy
  VarName1 := Expr1
    ...
  VarNamen := Exprn
  modify Expr0 return Exprr
: Typer

4.5.6 Examples

Examples

Here are a few example queries and their corresponding static typing. In each case, if the query passes static typing, its static type is the empty type.

  • insert node <x/> into <a/>

    Passes static typing

  • insert node 1 into <a/>

    Passes static typing

  • insert node 1 into (<a/>,<a/>)

    Fails static typing because the target expression does not return a single node

  • insert node (element a {()}, attribute b {()}) into <doc/>

    Fails static typing because the attribute node is not at the head of the insertion list

  • insert node <x/> into //a

    Fails static typing because the target expression must not return a single node (assuming the schema allows //a to return multiple a elements)

  • rename node <a/> as "b"

    Passes static typing

  • rename node <a/> as 1

    Fails static typing because the new name does not have one of the permissible types

5 Conformance

This section defines the conformance criteria for an XQuery processor. In this section, the following terms are used to indicate the requirement levels defined in [RFC 2119]. [Definition: MUST means that the item is an absolute requirement of the specification.] [Definition: MAY means that an item is truly optional.] [Definition: SHOULD means that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.]

An XQuery processor that claims to conform to this specification MUST include a claim of Minimal Conformance as defined in [5.1 Minimal Conformance]. In addition to a claim of Minimal Conformance, it MAY claim conformance to one or more optional features defined in [5.2 Optional Features].

5.1 Minimal Conformance

Minimal Conformance to this specification MUST include all of the following items:

  1. Minimal Conformance to [XQuery 1.0].

  2. Support for everything specified in this document except those features specified in [5.2 Optional Features] to be optional and [E XML Syntax (XQueryX) for XQuery Update Facility 1.0]. If an implementation does not provide a given optional feature, it MUST implement any requirements specified in [5.2 Optional Features] for implementations that do not provide that feature.

  3. A definition of every item specified to be implementation-defined, unless that item is part of an optional feature that is not supported by the implementation. A list of implementation-defined items can be found in [B Implementation-Defined Items].

    Note:

    Implementations are not required to define items specified to be implementation-dependent.

5.2 Optional Features

An implementation of XQuery that includes the Update Facility MAY also support the Optional Features of [XQuery 1.0]. These are Schema Import Feature, Schema Validation Feature, Static Typing Feature, Full Axis Feature, Module Feature, and Serialization Feature.

If an implementation claims support of the Static Typing Feature, then it MAY also claim support of the Update Facility Static Typing Feature.

5.2.1 Update Facility Static Typing Feature

[Definition: The Update Facility Static Typing Feature provides support for the static semantics defined in [4 Static Typing Feature], and requires implementations to detect and report type errors during the static analysis phase.]

If an implementation does not support the Update Static Typing Feature, but can nevertheless determine during the static analysis phase that an expression, if evaluated, will necessarily raise a type error at run time, the implementation MAY raise that error during the static analysis phase. The choice of whether to raise such an error at analysis time is implementation-dependent.

Note:

An implementation that does not support the Update Static Typing Feature is not required to raise type errors during the static analysis phase; however, it MUST detect and raise non-type-related static errors during the static analysis phase.

6 XQueryX Conformance

This section defines the conformance criteria for an XQueryX processor that includes the Update Facility.

In this section, the terms MUST, MAY, and SHOULD are used as defined in [5 Conformance].

An XQueryX processor that claims to conform to this specification MUST implement the XQueryX syntax as defined in [E XML Syntax (XQueryX) for XQuery Update Facility 1.0] and include a claim of Minimal Conformance as defined in [5.1 Minimal Conformance]. In addition to a claim of Minimal Conformance, it MAY claim conformance to one or more optional features defined in [5.2 Optional Features].

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" 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" ExprSingle
[44]    CaseClause    ::=    "case" ("$" VarName "as")? SequenceType "return" 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 (S PragmaContents)? "#)"
[67]    PragmaContents    ::=    (Char* - (Char* '#)' Char*))
[68]    PathExpr    ::=    ("/" RelativePathExpr?)
| ("//" RelativePathExpr)
| RelativePathExpr
[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)
[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)*)? ")"
[94]    Constructor    ::=    DirectConstructor
| ComputedConstructor
[95]    DirectConstructor    ::=    DirElemConstructor
| DirCommentConstructor
| DirPIConstructor
[96]    DirElemConstructor    ::=    "<" QName DirAttributeList ("/>" | (">" DirElemContent* "</" QName S? ">"))
[97]    DirAttributeList    ::=    (S (QName S? "=" S? DirAttributeValue)?)*
[98]    DirAttributeValue    ::=    ('"' (EscapeQuot | QuotAttrValueContent)* '"')
| ("'" (EscapeApos | AposAttrValueContent)* "'")
[99]    QuotAttrValueContent    ::=    QuotAttrContentChar
| CommonContent
[100]    AposAttrValueContent    ::=    AposAttrContentChar
| CommonContent
[101]    DirElemContent    ::=    DirectConstructor
| CDataSection
| CommonContent
| ElementContentChar
[102]    CommonContent    ::=    PredefinedEntityRef | CharRef | "{{" | "}}" | EnclosedExpr
[103]    DirCommentConstructor    ::=    "<!--" DirCommentContents "-->"
[104]    DirCommentContents    ::=    ((Char - '-') | ('-' (Char - '-')))*
[105]    DirPIConstructor    ::=    "<?" PITarget (S DirPIContents)? "?>"
[106]    DirPIContents    ::=    (Char* - (Char* '?>' Char*))
[107]    CDataSection    ::=    "<![CDATA[" CDataSectionContents "]]>"
[108]    CDataSectionContents    ::=    (Char* - (Char* ']]>' Char*))
[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    ::=    "?" | "*" | "+"
[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]    InsertExprTargetChoice    ::=    (("as" ("first" | "last"))? "into")
| "after"
| "before"
[143]    InsertExpr    ::=    "insert" ("node" | "nodes") SourceExpr InsertExprTargetChoice TargetExpr
[144]    DeleteExpr    ::=    "delete" ("node" | "nodes") TargetExpr
[145]    ReplaceExpr    ::=    "replace" ("value" "of")? "node" TargetExpr "with" ExprSingle
[146]    RenameExpr    ::=    "rename" "node" TargetExpr "as" NewNameExpr
[147]    SourceExpr    ::=    ExprSingle
[148]    TargetExpr    ::=    ExprSingle
[149]    NewNameExpr    ::=    ExprSingle
[150]    TransformExpr    ::=    "copy" "$" VarName ":=" ExprSingle ("," "$" VarName ":=" ExprSingle)* "modify" ExprSingle "return" ExprSingle

A.1 Terminal Symbols

[151]    IntegerLiteral    ::=    Digits
[152]    DecimalLiteral    ::=    ("." Digits) | (Digits "." [0-9]*)
[153]    DoubleLiteral    ::=    (("." Digits) | (Digits ("." [0-9]*)?)) [eE] [+-]? Digits
[154]    StringLiteral    ::=    ('"' (PredefinedEntityRef | CharRef | EscapeQuot | [^"&])* '"') | ("'" (PredefinedEntityRef | CharRef | EscapeApos | [^'&])* "'")
[155]    PredefinedEntityRef    ::=    "&" ("lt" | "gt" | "amp" | "quot" | "apos") ";"
[156]    EscapeQuot    ::=    '""'
[157]    EscapeApos    ::=    "''"
[158]    ElementContentChar    ::=    Char - [{}<&]
[159]    QuotAttrContentChar    ::=    Char - ["{}<&]
[160]    AposAttrContentChar    ::=    Char - ['{}<&]
[161]    Comment    ::=    "(:" (CommentContents | Comment)* ":)"
[162]    PITarget    ::=    [http://www.w3.org/TR/REC-xml#NT-PITarget]XML
[163]    CharRef    ::=    [http://www.w3.org/TR/REC-xml#NT-CharRef]XML
[164]    QName    ::=    [http://www.w3.org/TR/REC-xml-names/#NT-QName]Names
[165]    NCName    ::=    [http://www.w3.org/TR/REC-xml-names/#NT-NCName]Names
[166]    S    ::=    [http://www.w3.org/TR/REC-xml#NT-S]XML
[167]    Char    ::=    [http://www.w3.org/TR/REC-xml#NT-Char]XML

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

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

B Implementation-Defined Items

The following items in this specification are implementation-defined:

  1. The revalidation modes that are supported by this implementation.

  2. The default revalidation mode for this implementation.

  3. The mechanism (if any) by which an external function can return an XDM instance and/or a pending update list to the invoking query.

  4. The semantics of fn:put(), including the kinds of nodes accepted as operands by this function.

C References

C.1 Normative References

XQuery Update Facility 1.0 Requirements
XQuery Update Facility 1.0 Requirements, Don Chamberlin and Jonathan Robie, Editors. World Wide Web Consortium, 25 January 2011. This version is http://www.w3.org/TR/2011/NOTE-xquery-update-10-requirements-20110125/. The latest version is available at http://www.w3.org/TR/xquery-update-10-requirements/.
XQuery 1.0 and XPath 2.0 Data Model
XQuery 1.0 and XPath 2.0 Data Model (XDM) (Second Edition), Norman Walsh, Mary Fernández, Ashok Malhotra, et. al., Editors. World Wide Web Consortium, 14 December 2010. This version is http://www.w3.org/TR/2010/REC-xpath-datamodel-20101214/. The latest version is available at http://www.w3.org/TR/xpath-datamodel/.
XQuery 1.0
XQuery 1.0: An XML Query Language (Second Edition), Don Chamberlin, Anders Berglund, Scott Boag, et. al., Editors. World Wide Web Consortium, 14 December 2010. This version is http://www.w3.org/TR/2010/REC-xquery-20101214/. The latest version is available at http://www.w3.org/TR/xquery/.
XQuery 1.0 and XPath 2.0 Functions and Operators
XQuery 1.0 and XPath 2.0 Functions and Operators (Second Edition), Ashok Malhotra, Jim Melton, and Norman Walsh, Editors. World Wide Web Consortium, 14 December 2010. This version is http://www.w3.org/TR/2010/REC-xpath-functions-20101214/. The latest version is available at http://www.w3.org/TR/xpath-functions/.
XQueryX 1.0
XML Syntax for XQuery 1.0 (XQueryX) (Second Edition), Jim Melton and Subramanian Muralidhar, Editors. World Wide Web Consortium, 14 December 2010. This version is http://www.w3.org/TR/2010/REC-xqueryx-20101214/. The latest version is available at http://www.w3.org/TR/xqueryx/.
XQuery 1.0 and XPath 2.0 Formal Semantics
XQuery 1.0 and XPath 2.0 Formal Semantics (Second Edition), Jérôme Siméon, Denise Draper, Peter Frankhauser, et. al., Editors. World Wide Web Consortium, 14 December 2010. This version is http://www.w3.org/TR/2010/REC-xquery-semantics-20101214/. The latest version is available at http://www.w3.org/TR/xquery-semantics/.
RFC 2119
S. Bradner. Key Words for use in RFCs to Indicate Requirement Levels. IETF RFC 2119. See http://www.ietf.org/rfc/rfc2119.txt.

C.2 Non-normative References

XML Patch Operations
Internet Engineering Task Force. An Extensible Markup Language (XML) Patch Operations Framework Utilizing XML Path Language (XPath) Selectors.. See http://datatracker.ietf.org/doc/draft-ietf-simple-xml-patch-ops/ .
XQuery Update Facility 1.0 Use Cases
XQuery Update Facility 1.0 Use Cases, Iona Manolescu and Jonathan Robie, Editors. World Wide Web Consortium, 25 January 2011. This version is http://www.w3.org/TR/2011/NOTE-xquery-update-10-use-cases-20110125/. The latest version is available at http://www.w3.org/TR/xquery-update-10-use-cases/.

D Error Conditions

D.1 New Error Codes

err:XUST0001

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

  1. The topmost expression in the body of a query.

  2. The modify clause of a transform expression.

  3. The return clause of a FLWOR expression.

  4. The return clauses of a typeswitch expression in which every return clause contains an updating expression or a vacuous expression.

  5. The then and else clauses of a conditional statement in which both the then and else clauses contain either an updating expression or a vacuous expression.

  6. An operand of a comma expression in which each operand is either an updating expression or a vacuous expression.

  7. The content of a parenthesized expression.

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

err:XUST0002

It is a static error if a simple expression that is not a vacuous expression is used in one of the following positions:

  1. The modify clause of a transform expression.

  2. The top-level expression in the body of a function declaration in which the keyword updating is specified.

err:XUST0003

It is a static error if a Prolog contains more than one revalidation declaration.

err:XUTY0004

It is a type error if the insertion sequence of an insert expression contains an attribute node following a node that is not an attribute node.

err:XUTY0005

In an insert expression where into, as first into, or as last into is specified, it is a type error if the target expression returns a non-empty result that does not consist of a single element or document node.

err:XUTY0006

In an insert expression where before or after is specified, it is a type error if the target expression returns a non-empty result that does not consist of a single element, text, comment, or processing instruction node.

err:XUTY0007

It is a type error if the target expression of a delete expression does not return a sequence of zero or more nodes.

err:XUTY0008

In a replace expression, it is a type error if the target expression returns a non-empty result that does not consist of a single element, attribute, text, comment, or processing instruction node.

err:XUDY0009

In a replace expression where value of is not specified, it is a dynamic error if the node returned by the target expression does not have a parent.

err:XUTY0010

In a replace expression where value of is not specified and the target is an element, text, comment, or processing instruction node, it is a type error if the replacement sequence does not consist of zero or more element, text, comment, or processing instruction nodes.

err:XUTY0011

In a replace expression where value of is not specified and the target is an attribute node, it is a type error if the replacement sequence does not consist of zero or more attribute nodes.

err:XUTY0012

In a rename expression, it is a type error if the target expression returns a non-empty result that does not consist of a single element, attribute, or processing instruction node.

err:XUTY0013

In a transform expression, it is a type error if a source expression in the copy clause does not return a single node.

err:XUDY0014

In a transform expression, it is a dynamic error if the modify clause modifies any node that was not created by the copy clause.

err:XUDY0015

It is a dynamic error if any node is the target of more than one rename expression within the same query.

err:XUDY0016

It is a dynamic error if any node is the target of more than one replace expression (without value of being specified) within the same query.

err:XUDY0017

It is a dynamic error if any node is the target of more than one replace value of expression within the same query.

err:XUDY0018

It is a dynamic error if a function that was declared to be external but not updating returns a non-empty pending update list.

err:XUDY0019

It is a dynamic error if a function that was declared to be both external and updating returns a non-empty data model instance.

err:XUDY0021

It is a dynamic error if the XDM instance that would result from applying all the updates in a query violates any constraint specified in [XQuery 1.0 and XPath 2.0 Data Model]. In this case, none of the updates in the query are made effective.

err:XUTY0022

It is a type error if an insert expression specifies the insertion of an attribute node into a document node.

err:XUDY0023

It is a dynamic error if an insert, replace, or rename expression affects an element node by introducing a new namespace binding that conflicts with one of its existing namespace bindings.

err:XUDY0024

It is a dynamic error if the effect of a set of updating expressions is to introduce conflicting namespace bindings into an element node.

err:XUDY0025

(Not currently used.)

err:XUST0026

It is a static error if a revalidation declaration in a Prolog specifies a revalidation mode that is not supported by the current implementation.

err:XUDY0027

It is a dynamic error if the target expression of an insert, replace, or rename expression evaluates to an empty sequence.

err:XUST0028

It is a static error if a function declaration specifies both updating and a return type.

err:XUDY0029

In an insert expression where before or after is specified, it is a dynamic error if the node returned by the target expression does not have a parent.

err:XUDY0030

It is a dynamic error if an insert expression specifies the insertion of an attribute node before or after a child of a document node.

err:XUDY0031

It is a dynamic error if multiple calls to fn:put in the same snapshot specify the same URI (after resolution of relative URIs).

err:FOUP0001

It is a dynamic error if the first operand of fn:put is not a node of a supported kind.

err:FOUP0002

It is a dynamic error if the second operand of fn:put is not a valid lexical representation of the xs:anyURI type.

D.2 Amendments to Existing Error Codes

err:XPST0005

During the analysis phase, it is a static error if the static type assigned to a simple expression other than ( ) or data(( )) is empty-sequence( ).

err:XQDY0026

It is a dynamic error if a constructor or replace expression would result in a processing instruction node whose content includes the string "?>".

err:XQDY0041

It is a dynamic error if the name assigned to a processing node by a constructor or rename expression cannot be cast to the type xs:NCName.

err:XQDY0072

It is a dynamic error if a constructor or replace expression would result in a comment node whose content ends with a hyphen or contains two adjacent hyphens.

err:XQDY0074

It is a dynamic error if the value of the name expression in a computed element constructor, computed attribute constructor, or rename expression cannot be converted to an expanded QName (for example, because it contains a namespace prefix not found in the statically known namespaces.)

E XML Syntax (XQueryX) for XQuery Update Facility 1.0

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

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

E.1 Schema

This section specifies the two XML Schemas that define the complex types and elements for XQueryX in support of XQuery Update Facility 1.0, including changes to the prolog and the addition of several new expressions.


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

<!-- Initial creation                  2006-08-17: Jim Melton -->
<!-- Added ufRevalidationDecl          2006-08-21: Jim Melton -->
<!-- Overhaul to bring up to date      2007-08-07: Jim Melton -->
<!-- Reconfirmed correctness for CR    2008-02-27: Jim Melton -->

  <xsd:import namespace="http://www.w3.org/2005/XQueryX"
     schemaLocation="http://www.w3.org/2007/xquery-update-10/
xquery-update-10-xqueryx-redef.xsd"/>


  <!-- Add revalidationDecl to alternatives in prolog setters -->
  <xsd:element name="revalidationDecl"
               substitutionGroup="xqx:prologPartOneItem">
    <xsd:simpleType>
      <xsd:restriction base="xsd:NMTOKEN">
        <xsd:enumeration value="strict"/>
        <xsd:enumeration value="lax"/>
        <xsd:enumeration value="skip"/>
      </xsd:restriction>
    </xsd:simpleType>
  </xsd:element>


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

  <!-- Make the update facilities subst grp part of expr grp  -->
  <xsd:element name="expr" type="xqxuf:expr" abstract="true"
               substitutionGroup="xqx:expr"/>


  <!-- InsertExpr                                             -->
  <xsd:complexType name="insertExpr">
    <xsd:complexContent>
      <xsd:extension base="xqxuf:expr">
        <xsd:sequence>
          <xsd:element name="sourceExpr"
                       type="xqx:exprWrapper"/>
          <xsd:choice>
            <xsd:element name="insertInto">
              <xsd:complexType>
                <xsd:sequence minOccurs="0" maxOccurs="1">
                  <xsd:choice>
                    <xsd:element name="insertAsFirst" 
                                 type="xqx:emptyContent"/>
                    <xsd:element name="insertAsLast" 
                                 type="xqx:emptyContent"/>
                  </xsd:choice>
                </xsd:sequence>
              </xsd:complexType>
            </xsd:element>
            <xsd:element name="insertAfter"
                         type="xqx:emptyContent"/>
            <xsd:element name="insertBefore"
                         type="xqx:emptyContent"/>
          </xsd:choice>
          <xsd:element name="targetExpr"
                       type="xqx:exprWrapper"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="insertExpr" type="xqxuf:insertExpr" 
               substitutionGroup="xqxuf:expr"/>


  <!-- DeleteExpr                                             -->
  <xsd:complexType name="deleteExpr">
    <xsd:complexContent>
      <xsd:extension base="xqxuf:expr">
        <xsd:sequence>
         <xsd:element name="targetExpr"
                      type="xqx:exprWrapper"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="deleteExpr" type="xqxuf:deleteExpr" 
               substitutionGroup="xqxuf:expr"/>


  <!-- ReplaceExpr                                            -->
  <xsd:complexType name="replaceExpr">
    <xsd:complexContent>
      <xsd:extension base="xqxuf:expr">
        <xsd:sequence>
          <xsd:element name="replaceValue"
                       type="xqx:emptyContent"
                       minOccurs="0" maxOccurs="1"/>
          <xsd:element name="targetExpr"
                       type="xqx:exprWrapper"/>
          <xsd:element name="replacementExpr"
                       type="xqx:exprWrapper"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="replaceExpr" type="xqxuf:replaceExpr" 
               substitutionGroup="xqxuf:expr"/>


  <!-- RenameExpr                                             -->
  <xsd:complexType name="renameExpr">
    <xsd:complexContent>
      <xsd:extension base="xqxuf:expr">
        <xsd:sequence>
          <xsd:element name="targetExpr"
                       type="xqx:exprWrapper"/>
          <xsd:element name="newNameExpr"
                       type="xqx:exprWrapper"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="renameExpr" type="xqxuf:renameExpr" 
               substitutionGroup="xqxuf:expr"/>


  <!-- TransformExpr                                          -->
  <xsd:complexType name="transformExpr">
    <xsd:complexContent>
      <xsd:extension base="xqxuf:expr">
        <xsd:sequence>
          <xsd:element name="transformCopies">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="transformCopy" minOccurs="1" 
                             maxOccurs="unbounded">
                  <xsd:complexType>
                    <xsd:sequence>
                      <xsd:element ref="xqx:varRef"/>
                      <xsd:element name="copySource"
                                   type="xqx:exprWrapper"/>
                    </xsd:sequence>
                  </xsd:complexType>
                </xsd:element>
              </xsd:sequence>
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="modifyExpr"
                       type="xqx:exprWrapper"/>
          <xsd:element name="returnExpr"
                       type="xqx:exprWrapper"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>

  <xsd:element name="transformExpr" type="xqxuf:transformExpr" 
               substitutionGroup="xqxuf:expr"/>


</xsd:schema>



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

<!-- Redefine one or more components of the XQueryX XML Schema -->
<xsd:redefine schemaLocation="http://www.w3.org/2005/XQueryX/xqueryx.xsd">

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

</xsd:redefine>

</xsd:schema>

E.2 Stylesheet

This section specifies the XSLT stylesheet that defines the semantics of XQueryX in support of XQuery Update Facility 1.0. It imports the XSLT stylesheet defined in [XQueryX 1.0], and provides additional templates that define the semantics of the XQueryX representation of XQuery Update Facility 1.0 by transforming that XQueryX representation into the human readable syntax of XQuery Update Facility 1.0.


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

<!-- Initial creation                  2006-08-17: Jim Melton -->
<!-- Added revalidationDecl            2006-08-21: Jim Melton -->
<!-- Bring up to date with spec        2007-08-07: Jim Melton -->
<!-- Surround updating exprs w/parens  2007-09-13: Jim Melton -->


<xsl:import href="http://www.w3.org/2005/XQueryX/xqueryx.xsl"/>


<!-- revalidationDecl                                         -->
<xsl:template match="xqxuf:revalidationDecl">
  <xsl:text>declare revalidation </xsl:text>
  <xsl:apply-templates/>
</xsl:template>


<!-- insertExpr                                               -->
<xsl:template match="xqxuf:insertExpr">
  <xsl:value-of select="$LPAREN"/>
  <xsl:text>insert nodes </xsl:text>
  <xsl:value-of select="$NEWLINE"/>
  <xsl:apply-templates select="xqxuf:sourceExpr"/>
  <xsl:value-of select="$NEWLINE"/>
  <xsl:apply-templates select="xqxuf:insertInto |
                               xqxuf:insertBefore |
                               xqxuf:insertAfter"/>
  <xsl:value-of select="$NEWLINE"/>
  <xsl:apply-templates select="xqxuf:targetExpr"/>
  <xsl:value-of select="$RPAREN"/>
</xsl:template>


<!-- sourceExpr                                               -->
<xsl:template match="xqxuf:sourceExpr">
  <xsl:apply-templates/>
</xsl:template>


<!-- insertInto                                               -->
<xsl:template match="xqxuf:insertInto">
  <xsl:if test="child::node()">
    <xsl:text>as </xsl:text>
  </xsl:if>
  <xsl:apply-templates/>
  <xsl:text>into </xsl:text>
</xsl:template>


<!-- insertAsFirst                                            -->
<xsl:template match="xqxuf:insertAsFirst">
  <xsl:text>first </xsl:text>
</xsl:template>


<!-- insertAsLast                                             -->
<xsl:template match="xqxuf:insertAsLast">
  <xsl:text>last </xsl:text>
</xsl:template>


<!-- insertAfter                                              -->
<xsl:template match="xqxuf:insertAfter">
  <xsl:text>after </xsl:text>
</xsl:template>


<!-- insertBefore                                             -->
<xsl:template match="xqxuf:insertBefore">
  <xsl:text>before </xsl:text>
</xsl:template>


<!-- targetExpr                                               -->
<xsl:template match="xqxuf:targetExpr">
  <xsl:apply-templates/>
</xsl:template>


<!-- deleteExpr                                               -->
<xsl:template match="xqxuf:deleteExpr">
  <xsl:value-of select="$LPAREN"/>
  <xsl:text>delete nodes </xsl:text>
  <xsl:apply-templates/>
  <xsl:value-of select="$RPAREN"/>
</xsl:template>


<!-- replaceExpr                                              -->
<xsl:template match="xqxuf:replaceExpr">
  <xsl:value-of select="$LPAREN"/>
  <xsl:text>replace </xsl:text>
  <xsl:if test="xqxuf:replaceValue">
    <xsl:text>value of </xsl:text>
  </xsl:if>
  <xsl:text>node </xsl:text>
  <xsl:apply-templates select="xqxuf:targetExpr"/>
  <xsl:text> with </xsl:text>
  <xsl:apply-templates select="xqxuf:replacementExpr"/>
  <xsl:value-of select="$RPAREN"/>
</xsl:template>


<!-- replacementExpr                                          -->
<xsl:template match="xqxuf:replacementExpr">
  <xsl:apply-templates/>
</xsl:template>


<!-- renameExpr                                               -->
<xsl:template match="xqxuf:renameExpr">
  <xsl:value-of select="$LPAREN"/>
  <xsl:text>rename node </xsl:text>
  <xsl:apply-templates select="xqxuf:targetExpr"/>
  <xsl:text> as </xsl:text>
  <xsl:apply-templates select="xqxuf:newNameExpr"/>
  <xsl:value-of select="$RPAREN"/>
</xsl:template>


<!-- newNameExpr                                              -->
<xsl:template match="xqxuf:newNameExpr">
  <xsl:apply-templates/>
</xsl:template>


<!-- transformExpr                                            -->
<xsl:template match="xqxuf:transformExpr">
  <xsl:value-of select="$LPAREN"/>
  <xsl:text>copy </xsl:text>
  <xsl:apply-templates select="xqxuf:transformCopies"/>
  <xsl:value-of select="$NEWLINE"/>
  <xsl:text>  modify </xsl:text>
  <xsl:apply-templates select="xqxuf:modifyExpr"/>
  <xsl:value-of select="$NEWLINE"/>
  <xsl:text>  return </xsl:text>
  <xsl:apply-templates select="xqxuf:returnExpr"/>
  <xsl:value-of select="$RPAREN"/>
</xsl:template>


<!-- Part of transformExpr                                    -->
<xsl:template match="xqxuf:transformCopies">
  <xsl:call-template name="commaSeparatedList"/>
</xsl:template>


<!-- Part of transformExpr                                    -->
<xsl:template match="xqxuf:transformCopy">
  <xsl:apply-templates select="xqx:varRef"/>
  <xsl:text> := </xsl:text>
  <xsl:apply-templates select="xqxuf:copySource"/>
</xsl:template>

<!-- Part of transformExpr                                    -->
<xsl:template match="xqxuf:copySource">
  <xsl:apply-templates/>
</xsl:template>

<!-- Part of transformExpr                                    -->
<xsl:template match="xqxuf:modifyExpr">
  <xsl:apply-templates/>
</xsl:template>


<!-- Part of transformExpr                                    -->
<xsl:template match="xqxuf:returnExpr">
  <xsl:apply-templates/>
</xsl:template>


<!-- Over-ride the template for functionDecl in XQueryX.xsd   -->
  <xsl:template match="xqx:functionDecl" priority="100">
    <xsl:text>declare </xsl:text>
    <xsl:if test="@xqx:updatingFunction and
                  @xqx:updatingFunction = 'true'">
      <xsl:text>updating </xsl:text>
    </xsl:if>
    <xsl:text>function </xsl:text>
    <xsl:apply-templates select="xqx:functionName"/>
    <xsl:apply-templates select="xqx:paramList"/>
    <xsl:apply-templates select="xqx:typeDeclaration"/>
    <xsl:apply-templates select="xqx:functionBody"/>
    <xsl:if test="xqx:externalDefinition">
      <xsl:text> external </xsl:text>
    </xsl:if>
  </xsl:template>


</xsl:stylesheet>

E.3 Example

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

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

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

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

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

This example is based on Q6 from [XQuery Update Facility 1.0 Use Cases], use case Parts: "modifying recursive documents":

E.3.1 XQuery Representation

for $keyword at $i in ("car", "skateboard", "canoe"),
    $parent in doc("part-tree.xml")//part[@name=$keyword]
let $descendants := $parent//part
for $p in ($parent, $descendants)
return 
  replace value of node $p/@partid with $i*1000+$p/@partid

E.3.2 XQueryX Representation

<?xml version="1.0"?>
<xqx:module xmlns:xqxuf="http://www.w3.org/2007/xquery-update-10"
            xmlns:xqx="http://www.w3.org/2005/XQueryX"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.w3.org/2007/xquery-update-10
    http://www.w3.org/2007/xquery-update-10/xquery-update-10-xqueryx.xsd
    http://www.w3.org/2005/XQueryX
    http://www.w3.org/2005/XQueryX/xqueryx.xsd">

  <xqx:versionDecl>
    <xqx:version>1.0</xqx:version>
  </xqx:versionDecl>
  <xqx:mainModule>
    <xqx:queryBody>
      <xqx:flworExpr>
        <xqx:forClause>
          <xqx:forClauseItem>
            <xqx:typedVariableBinding>
              <xqx:varName>keyword</xqx:varName>
            </xqx:typedVariableBinding>
            <xqx:positionalVariableBinding>i
            </xqx:positionalVariableBinding>
            <xqx:forExpr>
              <xqx:sequenceExpr>
                <xqx:stringConstantExpr>
                  <xqx:value>car</xqx:value>
                </xqx:stringConstantExpr>
                <xqx:stringConstantExpr>
                  <xqx:value>skateboard</xqx:value>
                </xqx:stringConstantExpr>
                <xqx:stringConstantExpr>
                  <xqx:value>canoe</xqx:value>
                </xqx:stringConstantExpr>
              </xqx:sequenceExpr>
            </xqx:forExpr>
          </xqx:forClauseItem>
          <xqx:forClauseItem>
            <xqx:typedVariableBinding>
              <xqx:varName>parent</xqx:varName>
            </xqx:typedVariableBinding>
            <xqx:forExpr>
              <xqx:pathExpr>
                <xqx:stepExpr>
                  <xqx:filterExpr>
                    <xqx:functionCallExpr>
                      <xqx:functionName
                        xqx:prefix="fn">doc</xqx:functionName>
                      <xqx:arguments>
                        <xqx:stringConstantExpr>
                          <xqx:value>part-tree.xml</xqx:value>
                        </xqx:stringConstantExpr>
                      </xqx:arguments>
                    </xqx:functionCallExpr>
                  </xqx:filterExpr>
                </xqx:stepExpr>
                <xqx:stepExpr>
                  <xqx:xpathAxis>descendant-or-self</xqx:xpathAxis>
                  <xqx:nameTest>part</xqx:nameTest>
                  <xqx:predicates>
                    <xqx:equalOp>
                      <xqx:firstOperand>
                        <xqx:pathExpr>
                          <xqx:stepExpr>
                            <xqx:xpathAxis>attribute</xqx:xpathAxis>
                            <xqx:nameTest>name</xqx:nameTest>
                          </xqx:stepExpr>
                        </xqx:pathExpr>
                      </xqx:firstOperand>
                      <xqx:secondOperand>
                        <xqx:varRef>
                          <xqx:name>keyword</xqx:name>
                        </xqx:varRef>
                      </xqx:secondOperand>
                    </xqx:equalOp>
                  </xqx:predicates>
                </xqx:stepExpr>
              </xqx:pathExpr>
            </xqx:forExpr>
          </xqx:forClauseItem>
        </xqx:forClause>
        <xqx:letClause>
          <xqx:letClauseItem>
            <xqx:typedVariableBinding>
              <xqx:varName>descendants</xqx:varName>
            </xqx:typedVariableBinding>
            <xqx:letExpr>
              <xqx:pathExpr>
                <xqx:stepExpr>
                  <xqx:filterExpr>
                    <xqx:varRef>
                      <xqx:name>parent</xqx:name>
                    </xqx:varRef>
                  </xqx:filterExpr>
                </xqx:stepExpr>
                <xqx:stepExpr>
                  <xqx:xpathAxis>descendant-or-self</xqx:xpathAxis>
                  <xqx:nameTest>part</xqx:nameTest>
                </xqx:stepExpr>
              </xqx:pathExpr>
            </xqx:letExpr>
          </xqx:letClauseItem>
        </xqx:letClause>
        <xqx:forClause>
          <xqx:forClauseItem>
            <xqx:typedVariableBinding>
              <xqx:varName>p</xqx:varName>
            </xqx:typedVariableBinding>
            <xqx:forExpr>
              <xqx:sequenceExpr>
                <xqx:varRef>
                  <xqx:name>parent</xqx:name>
                </xqx:varRef>
                <xqx:varRef>
                  <xqx:name>descendants</xqx:name>
                </xqx:varRef>
              </xqx:sequenceExpr>
            </xqx:forExpr>
          </xqx:forClauseItem>
        </xqx:forClause>
        <xqx:returnClause>
          <xqxuf:replaceExpr>
            <xqxuf:replaceValue/>
            <xqxuf:targetExpr>
              <xqx:pathExpr>
                <xqx:stepExpr>
                  <xqx:filterExpr>
                    <xqx:varRef>
                      <xqx:name>p</xqx:name>
                    </xqx:varRef>
                  </xqx:filterExpr>
                </xqx:stepExpr>
                <xqx:stepExpr>
                  <xqx:xpathAxis>attribute</xqx:xpathAxis>
                  <xqx:nameTest>partid</xqx:nameTest>
                </xqx:stepExpr>
              </xqx:pathExpr>
            </xqxuf:targetExpr>
            <xqxuf:replacementExpr>
              <xqx:addOp>
                <xqx:firstOperand>
                  <xqx:multiplyOp>
                    <xqx:firstOperand>
                      <xqx:varRef>
                        <xqx:name>i</xqx:name>
                      </xqx:varRef>
                    </xqx:firstOperand>
                    <xqx:secondOperand>
                      <xqx:integerConstantExpr>
                        <xqx:value>1000</xqx:value>
                      </xqx:integerConstantExpr>
                    </xqx:secondOperand>
                  </xqx:multiplyOp>
                </xqx:firstOperand>
                <xqx:secondOperand>
                  <xqx:pathExpr>
                    <xqx:stepExpr>
                      <xqx:filterExpr>
                        <xqx:varRef>
                          <xqx:name>p</xqx:name>
                        </xqx:varRef>
                      </xqx:filterExpr>
                    </xqx:stepExpr>
                    <xqx:stepExpr>
                      <xqx:xpathAxis>attribute</xqx:xpathAxis>
                      <xqx:nameTest>partid</xqx:nameTest>
                    </xqx:stepExpr>
                  </xqx:pathExpr>
                </xqx:secondOperand>
              </xqx:addOp>
            </xqxuf:replacementExpr>
          </xqxuf:replaceExpr>
        </xqx:returnClause>
      </xqx:flworExpr>
    </xqx:queryBody>
  </xqx:mainModule>
</xqx:module>

E.3.3 Transformed XQuery Representation

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

 xquery version "1.0";

( for $keyword at $i in ("car", "skateboard", "canoe"),
 $parent in
   fn:doc("part-tree.xml")/descendant-or-self::part
     [(attribute::name = $keyword)]
 let $descendants:=$parent/descendant-or-self::part
 for $p in ($parent, $descendants)
 return
   replace value of node $p/attribute::partid
     with (($i*1000)+$p/attribute::partid)
)

F Glossary (Non-Normative)

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

basic updating expression

A basic updating expression is an insert, delete, replace, or rename expression, or a call to an updating function.

conflict

Two namespace bindings are said to conflict if their namespace prefixes (or absence thereof) are the same but their namespace URI's (or absence thereof) are different.

data model

The term data model refers to the data model specified by [XQuery 1.0 and XPath 2.0 Data Model].

implied namespace binding

The implied namespace binding of a QName is the association of its namespace prefix (or absence thereof) with its namespace URI (or absence thereof).

mark

To mark a node means to identify the node as participating in a later operation.

may

MAY means that an item is truly optional.

must

MUST means that the item is an absolute requirement of the specification.

node identity

The term node identity denotes the unique identity that is a property of every node in an XDM instance (see Section 2.3 Node IdentityDM.)

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.

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.

should

SHOULD means that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

simple expression

A simple expression is any XQuery expression that is not an updating expression.

snapshot

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

static typing feature

The Update Facility Static Typing Feature provides support for the static semantics defined in [4 Static Typing Feature], and requires implementations to detect and report type errors during the static analysis phase.

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

Update primitives are the components of pending update lists. Each update primitive represents a node state change that has not yet been applied.

update routine

Update routines are sequences of actions that are used in the definition of XQuery semantics but do not appear on pending update lists.

updating expression

An updating expression is a basic updating expression or any expression (other than a transform expression) that directly contains an updating expression.

updating function

Functions whose declarations contain the keyword updating, and certain built-in functions including fn:put, are called updating functions.

vacuous expression

Certain expressions are defined in this specification to be vacuous expressions. These all have the characteristic that they can be determined statically to either return an empty sequence or raise an error.

G Rationale for Precedence of Update Primitives (Non-Normative)

In [3.2.2 upd:applyUpdates], semantic rules specify the order in which the update primitives on a pending update list are applied. The purpose of this ordering is to ensure that the result of applying the pending update list is deterministic. The order of application of the update primitives was derived from the following reasoning:

H Revision Log (Non-Normative)

The following substantive changes have been made to this document since the Candidate Recommendation of 9 June 2009. Minor editorial changes are not included in this log.

  1. Fixed a bug involving namespace propagation and default namespaces. Resolves Bug 9432.

  2. Added missing parameter to upd:applyUpdates(). Resolves Bug 9262.

  3. Added missing text governing namespace binding conflicts when the namespace prefix for an attribute is absent. Resolves Bug 9257.

  4. Fixed two errors governing namespace bindings created by upd:replaceNode(). The erroneous text said that the namespace binding was created on the attribute itself, rather than the parent element. Resolves Bug 9256.

  5. Added a note indicating that some examples are rejected by implementations that support static typing. See Bug 8006.

The following substantive changes have been made to this document since the Candidate Recommendation of 14 March 2008.

  1. Added a rule: the expression on the right-hand-side of a variable declaration the initializing expression) must be a simple expression. Resolves Bug 5699. Section affected: [2.2.2 Variable Declaration].

  2. When a rename expression operates on an attribute node, err:XUDY0023 can be raised only if the new name of the attribute is in a namespace. Renaming an attribute to a QName that has neither a namespace prefix nor a namespace URI is not an error, even if the parent element has a default namespace. Partial resolution of Bug 5629. Section affected: [2.4.4 Rename].

  3. When a upd:rename operation is applied to an element node, and the $newname operand is a QName that has neither a namespace prefix nor a namespace URI, part of the semantics of the operation is to remove the namespace binding for the empty prefix (if any) from the element node. Partial resolution of Bug 5629. Section affected: [3.1.11 upd:rename].

  4. Optional error err:XUDY0020 (deletion of a node that has no parent) is made part of the semantics of the delete expression (formerly it was described under the upd:delete primitive). Partial resolution of Bug 5632. Sections affected: [2.4.2 Delete], [3.1.7 upd:delete].

  5. Error err:XUDY0024 (updates introducing conflicting namespace bindings) is made part of the semantics of the insert and replace expressions. Also, consistency constraints on Pending Update Lists, raising err:XUDY0024 if multiple primitives on a PUL have conflicting namespace bindings, have been added to the semantics of upd:mergeUpdates and upd:applyUpdates. Checks for err:XUDY0024 are no longer part of the semantics of upd:insertAttributes, upd:replaceNode, or upd:rename. The net effect of these changes is to enable implementations to catch conflicting namespace bindings earlier and to associate them with specific expressions. Dynamic errors are no longer generated by individual update primitives on Pending Update Lists. Partial resolution of Bug 5632. Sections affected: [2.4.1 Insert], [2.4.3 Replace], [3.1.6 upd:insertAttributes], [3.1.8 upd:replaceNode], [3.1.11 upd:rename], [3.2.1 upd:mergeUpdates], [3.2.2 upd:applyUpdates].

  6. The following changes were made to the semantics of fn:put (resolving Bug 5646):

    1. fn:put now generates an update primitive called upd:put, which is held on the pending update list and applied after all other update primitives. Sections: [2.6.1 fn:put], [3.1.12 upd:put].

    2. It is an error to invoke fn:put more than once on the same URI within a snapshot. Sections: [2.4.6 Compatibility of Updating Expressions], [3.2.1 upd:mergeUpdates], [3.2.2 upd:applyUpdates], [D.1 New Error Codes].

    3. fn:put is classified as an updating function. Section: [2.2.3 Function Declaration].

  7. Moved the subsection on Function Declarations inside the section on Extensions to the Prolog. Resolves Bug 5701. Section affected: [2.2.3 Function Declaration]

  8. In the Static Typing Feature for XQuery Update Facility, err:XPST0005 applies only to simple expressions (not to updating expressions.) Resolves Bug 5700. Sections affected: [4.2 Change to Static Typing Rules of XQuery 1.0], [D.2 Amendments to Existing Error Codes].

  9. In the Static Type Analysis for TransformExpr, the static type of each copy-variable used to be the type inferred from its source expression; now it's just node().

No substantive changes have been made to this document since the Proposed Recommendation of 25 January 2011.