This document defines an update facility that extends the XML Query language, XQuery. The XQuery Update Facility provides expressions that can be used to make persistent changes to instances of the XQuery 1.0 and XPath 2.0 Data Model.
This is a
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document defines a facility for updating instances of the XQuery 1.0 and XPath 2.0
Data Model; the language is specified in the form of extensions to
Since the last version of this document, several significant changes have been made.
Several new update primitives have been added, removing the need for the
compatibility table by introducing new mappings from updating expressions onto
update primitives.
Considerable clarification of the handling of namespace bindings have been made.
The semantics of node deletion and of parentless node value replacement have
been clarified.
Finally, the XQueryX specification for the XQuery Update Facility has been added
in an appendix.
Additional information about changes made since the last version of this document
can be found at
Of the XQuery Update Facility documents, only this document,
XQuery Update Facility 1.0, is a Last Call document.
The XQuery Update Facility Requirements
Public Last Call comments on this document and its open issues are invited.
Comments on this document are due by 31 October 2007.
Comments on this document should be made in W3C's
This document was produced by a group operating under the
September 2005: First internal draft
November 2005: Second internal draft
27 January 2006: First public working draft
8 May 2006: Second public working draft
11 July 2006: Third public working draft
28 August 2007: Last Call working draft
This document defines the syntax and semantics of an extension
to
The XQuery Update Facility 1.0 provides facilities to perform any or all
of the following operations on an
Insertion of a node.
Deletion of a node.
Modification of a node by changing
some of its properties while preserving its
Creation of a modified copy of a node with a new
As described in
The basic building block of XQuery is the expression. XQuery 1.0 provides
several kinds of expressions that can be composed with each other in
arbitrary ways. An XQuery 1.0 expression takes one or more
XQuery Update Facility 1.0 introduces a new category of expression called an
The extensions to XQuery 1.0 provided by XQuery Update Facility 1.0 may be characterized as follows:
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.
XQuery Update Facility 1.0 classifies XQuery expressions into the following categories: The definition of an
XQuery Update Facility 1.0 defines the places where updating and non-updating expressions can be used. In so doing, it makes small extensions to the syntax and semantics of certain existing expressions.
XQuery Update Facility 1.0 defines the following extensions to the XQuery processing model:
In XQuery 1.0, the result of each expression is an
In the current specification, no expression returns both a non-empty
XQuery Update Facility 1.0 also defines a set of
upd:applyUpdates
operation.
upd:applyUpdates
is an example of an update routine.
If the outermost expression in a query returns a upd:applyUpdates
is implicitly applied to this pending update list. This invocation of upd:applyUpdates
may raise an error (see
upd:applyUpdates
operation. XQuery Update Facility 1.0 currently defines an entire query as one snapshot.
This specification defines the semantics of updates to an
The Prolog is extended by adding a new kind of
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
The following definition is added to the XQuery static context
(documented in
strict
, lax
, or skip
,
is a component of the static context that controls the behavior of the
upd:revalidate
operation.
The following entry is added to the table of static context components
(documented in
Component: Revalidation mode
Default initial value: strict
.
Can be overwritten by an implementation: Yes (implementation defined.)
Can be overwritten by a query: Yes, overwritable by declaration in query prolog.
Scope: Global.
Consistency rules: Must be strict
, lax
, or skip
.
XQuery Update Facility 1.0 extends the syntax of
In general,
An insert expression is an 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 is preserved.
If multiple groups of nodes are inserted by multiple insert expressions
in the same
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 is preserved.
If multiple groups of nodes are inserted by multiple insert expressions
in the same
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 is preserved.
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.
Navigating by means of several bound variables, insert a new police report into the list of police reports for a particular accident.
The semantics of an insert expression are as follows:
$alist
be the sequence of attribute nodes in the insertion sequence. Let $clist
be the remainder of the insertion sequence, in its original order.
Either $alist
or $clist
or both may be empty.
The target expression must be a
If the result is an empty sequence,
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
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
If before
or after
is specified, the node returned by the target expression must have a non-empty parent
property
Let
$target
be the node returned by the target expression.
If $alist
is not empty and any form of into
is specified, the following checks are performed:
$target
must be an element node
No attribute node in $alist
may have a QName whose $target
If $alist
is not empty and before
or after
is specified, the following checks are performed:
parent($target)
must be an element node
No attribute node in $alist
may have a QName whose parent($target)
The result of the insert expression is an empty
If as first into
is specified, the
If $alist
is not empty, upd:insertAttributes($target, $alist)
If $clist
is not empty, upd:insertIntoAsFirst($target, $clist)
If as last into
is specified, the
If $alist
is not empty, upd:insertAttributes($target, $alist)
If $clist
is not empty, upd:insertIntoAsLast($target, $clist)
If into
is specified with neither as first
nor as last
, the
If $alist
is not empty, upd:insertAttributes($target, $alist)
If $clist
is not empty, upd:insertInto($target, $clist)
If before
is specified, let $parent
be the parent node of $target
. The
If $alist
is not empty, upd:insertAttributes($parent, $alist)
If $clist
is not empty, upd:insertBefore($target, $clist)
If after
is specified, let $parent
be the parent node of $target
. The
If $alist
is not empty, upd:insertAttributes($parent, $alist)
If $clist
is not empty, upd:insertAfter($target, $clist)
A delete expression deletes zero or more nodes from an node
and nodes
may be used interchangeably, regardless of how many nodes are actually deleted. A delete expression is an
Examples:
Delete the last author of the first book in a given bibliography.
Delete all email messages that are more than 365 days old.
The semantics of a delete expression are as follows:
The target expression must be a $tlist
be the list of nodes returned by
the target expression.
A new $tnode
in $tlist
, the following upd:delete($tnode)
. The resulting
pending update list (together with an empty
Since node deletions do not become effective until the end of a
The upd:delete($tnode)
primitive causes the given node to be detached from its parent after completion of the current query. If the given node has no parent, it is implementation-defined whether a dynamic error is raised
The effects of a delete expression on persistent storage (if any) are beyond the scope of this specification.
A replace expression is an value of
is specified.
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.
The semantics of this form of replace expression are as follows:
The expression following the keyword with
must be a $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.
The target expression must be a
If the result is an empty sequence,
If the result is non-empty and does not consist of a single element, attribute, text, comment, or processing instruction node,
If the result consists of a node whose parent property is empty,
Let
$target
be the node returned by the target expression, and let $parent
be its parent node.
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
If $target
is an attribute node, then:
$rlist
must consist exclusively of zero or more attribute nodes
No attribute node in $rlist
may have a QName whose $parent
The result of the replace expression is an empty upd:replaceNode($target, $rlist)
If value of
is specified,
a replace expression is used to modify the value of a node while preserving
its
Increase the price of the first book by ten percent.
The semantics of this form of replace expression are as follows:
The expression following the keyword with
must be a $text
be the result of this step.
The target expression must be a
If the result is an empty sequence,
If the result is non-empty and does not consist of a single element, attribute, text, comment, or processing instruction node,
Let
$target
be the node returned by the target expression.
If $target
is an element node, the result of the replace
expression is an empty upd:replaceElementContent($target, $text)
If $target
is an attribute, text, comment, or processing
instruction node, let $string
be the string value of the text node
constructed in Step 1. If Step 1 did not construct
a text node, let $string
be a zero-length string.
Then:
If $target
is a comment node, and $string
contains two adjacent hyphens or ends with a hyphen, a dynamic error is raised
If $target
is a processing instruction node, and $string
contains the substring "?>
", a dynamic error is raised
In the absence of errors, the result of a replace expression is an empty upd:replaceValue($target, $string)
.
A rename expression replaces the name
property of a
Examples:
Rename the first author
element of the first book to principal-author
.
Rename the first author
element of the first book to the QName that is the value of the variable $newname
.
The semantics of a rename expression are as follows:
The target expression must be a
If the result is an empty sequence,
If the result is non-empty and does not consist of a single element, attribute, or processing instruction node,
Let
$target
be the node returned by the target expression.
$QName
be this expanded QName.
The following checks are performed for error conditions:
If $target
is an element node, the "namespaces" property of $target
must not include any namespace binding that $QName
If $target
is an attribute node that has a parent, the "namespaces" property of parent($target)
must not include any namespace binding that $QName
If $target
is processing instruction node, $QName
must not include a non-empty namespace prefix.
The result of the rename expression is an empty upd:rename($target, $QName)
.
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
.
A transform expression can be used to create modified copies of existing nodes in an
Examples:
Return a sequence consisting of all employee
elements that have Java as a skill, excluding their salary
child-elements:
The following example copies a node, modifies the copy, and returns both the original node and the modified copy:
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:
The copy
clause contains one or more variable bindings, each of which consists of a variable name and an expression called the
The source expression must be a
The node returned by the source expression is a new node whose
The variable name is bound to the node returned by the source expression. 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.
The modify
clause must contain either an ( )
, or a call to the fn:error
function; otherwise a static error is raised modify
clause is evaluated, resulting in a $pul
be the pending update list generated by this step.
The following upd:applyUpdates($pul)
. The effect of this operation is to make the updates specified in the modify
clause effective on the copied nodes.
In the event of incompatible updates, the upd:applyUpdates
operation may raise an error, as described in
The return
clause must contain a 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.
The rules defining compatibility of
The effect of these rules is as follows:
If any node is affected by more than one rename
expression within a
If any node is affected by more than one replace
expression (without value of
being specified) within a
If any node is affected by more than one replace value of
expression within a
Within a given 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
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 $A
will consist of a single text node with the content "Goodbye"
.
XQuery Update Facility 1.0 provides extensions to the semantics of several existing kinds of XQuery expressions, as specified in this section.
The syntax of the FLWOR expression is not changed. Its semantics are extended as follows:
If a for
,
let
, where
, or order by
clause contains an
If the return
clause contains a
If the return
clause contains an
The semantics of the for
,
let
, where
, and order by
clauses are as specified in Section 3.8 of
For each tuple
generated by the previous step, the updating expression in the
return
clause is evaluated, resulting in a
All the upd:mergeUpdates
operation. The resulting merged pending update list is the
result of the FLWOR expression.
In the event of incompatible updates, the upd:mergeUpdates
operation may raise an error, as described in
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
.
The syntax of the typeswitch expression is not changed. Its semantics are extended as
follows (the term "branch" refers to any case
or default
clause in the typeswitch expression):
If the operand expression of a typeswitch is an
If any branch contains an
If the typeswitch expression is a
If the typeswitch expression is an ( )
, or a call to the fn:error
function; otherwise a static error is raised return
clause of the effective case (or default) is then evaluated, resulting
in a
The semantics of
conditional expressions are extended as follows (the term "branch" refers to the then
and else
clauses in the conditional expression):
If the if-clause contains an
If either branch contains an
If the conditional expression is a
If the conditional expression is an ( )
, or a call to the fn:error
function; otherwise a static error is raised then
or else
clause is selected and evaluated as specified in Section 3.10 of
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.
The semantics of
comma expressions (composed of one or more expressions concatenated by the comma operator, as described in Section 3.3.1 of
If any operand of the comma expression is an
If the comma expression is a
If the comma expression is an ( )
, or a call to the fn:error
function; otherwise a static error is raised upd:mergeUpdates
operation. The resulting merged
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.
The semantics of a parenthesized expression (any XQuery expression enclosed in parentheses) are extended as follows:
The category of a parenthesized expression is the same as the category of its operand expression, which may be an ( )
is a
The syntax of a function declaration is extended to include an optional keyword: updating
.
If updating
is not specified:
If external
is not specified, the EnclosedExpr in the function declaration must be a
If external
is specified, the external function must not return a non-empty
If updating
is specified:
A return type must not be specified
If external
is not specified, the EnclosedExpr in the function declaration must be an ( )
, or a call to the fn:error
function; otherwise a static error is raised
If external
is specified, the external function may return a non-empty
The means by which an external function returns an
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.
The semantics of a function call are extended as follows:
The function call is evaluated as specified in Section 3.1.5 of updating
keyword, the function call is an updating
keyword, the function call is a
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
In addition, the initializing expression of a variable declaration in a Prolog may not be an
XQuery Update Facility 1.0 provides extensions to XQuery built-in function library, as specified in this section.
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.
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
If
$uri
is not a valid lexical representation of the xs:anyURI
type, a dynamic error is
raised $uri
is a relative URI Reference, it is resolved
relative to the value of the base URI property in the static
context.
The semantics of fn:put
are implementation-defined,
since they occur completely 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.
The results of fn:put
do not become effective until after completion of the query containing the fn:put
function--that is, until after completion of the upd:applyUpdates
operation invoked by the outermost expression in the current query. The fn:put
function has no effect on the current query. (For example, it does not change the set of available documents or collections seen by the current query.)
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
The update primitives described in this section may be held on upd:applyUpdates
routine.
Inserts $content
immediately before $target
.
$target
must be an element, text, processing
instruction, or comment node with a non-empty parent
property. $content
must be a sequence containing only element, text, processing instruction,
and comment nodes.
Effects on nodes in $content
:
For each node in $content
, the parent
property is set to parent($target)
.
If the type-name
property of parent($target)
is xs:untyped
, then upd:setToUntyped()
is invoked on each element or attribute node in $content
.
Effects on parent($target)
:
The children
property of parent($target)
is modified to add the nodes in $content
just before $target
, preserving their order.
If at least one of the nodes in $content
is an element or text node, upd:removeType(parent($target))
is invoked.
Inserts $content
immediately after $target
.
$target
must be an element, text, processing
instruction, or comment node with a non-empty parent
property. $content
must be a sequence containing only element, text, processing instruction,
and comment nodes.
The semantics of upd:insertAfter
are identical to the semantics of upd:insertBefore
, except that Rule 2a is changed as follows:
The children
property of parent($target)
is modified to add the nodes in $content
just after $target
, preserving their order.
Inserts $content
as the children of $target
, in an implementation-dependent position.
$target
must be an element or document node. $content
must be a sequence containing only element, text, processing instruction,
and comment nodes.
The semantics of upd: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 include the nodes in $content
in implementation-dependent positions, preserving their relative order.
Inserts $content
as the first children of $target
.
$target
must be an element or document node. $content
must be a sequence containing only element, text, processing instruction,
and comment nodes.
The semantics of upd: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 include the nodes in $content
as the first children, preserving their order.
Inserts $content
as the last children of $target
.
$target
must be an element or document node. $content
must be a sequence containing only element, text, processing instruction,
and comment nodes.
The semantics of upd:insertIntoAsLast
are identical to the semantics of upd:insertBefore
, except that $target
is substituted everywhere for parent($target)
, and Rule 2a is changed as follows:
The children
property of $target
is changed to include the nodes in $content
as the last children, preserving their order.
Inserts $content
as attributes of $target
.
None
Error checks:
If the QNames of any two attribute nodes in $content
have
If the QName of any attribute node in $content
has an $target
, a dynamic error is raised
For each node $A
in $content
:
The parent
property of $A
is set to $target
.
If the type-name
property of $target
is xs:untyped
, then upd:setToUntyped($A)
is invoked.
The following properties of $target
are changed:
attributes
: Modified to include the nodes in $content
.
namespaces:
Modified to include namespace bindings for any attribute namespace prefixes in $content
that did not already have bindings.
upd:removeType($target)
is invoked.
None
If $target
has no parent, the $target
had no parent before execution of the query began.
If $target
has a parent node $P
, then:
The parent
property of $target
is set to empty.
If $target
is an attribute node, the attributes
property of $P
is modified to remove $target
.
If $target
is a non-attribute node, the children
property of $P
is modified to remove $target
.
If $target
is an element, attribute, or text node, and $P
is an element node, then upd:removeType($P)
is invoked.
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.
Multiple upd:delete
operations may be applied to the same node during execution of a query; this is not an error.
Replaces $target
with $replacement
.
$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.
Error checks:
If the QNames of any two attribute nodes in $replacement
have
If the QName of any attribute node in $replacement
has an parent($target)
, a dynamic error is raised
Effects on nodes in $replacement
:
For each node in $replacement
, the parent
property is set to parent($target)
.
If the type-name
property of parent($target)
is xs:untyped
, then upd:setToUntyped()
is invoked on each element node in $replacement
.
Effect on $target
:
The parent
property of $target
is set to empty.
Effects on parent($target)
:
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).
If $target
is an attribute node, the namespaces
property of parent($target)
is modified to include namespace bindings for any attribute namespace prefixes in $replacement
that did not already have bindings.
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.
upd:removeType(parent($target))
is invoked.
Replaces the string value of $target
with $string-value
.
$target
must be an attribute, text, comment, or processing instruction node.
If $target
is an attribute node:
string-value
of $target
is set to $string-value
.
upd:removeType($target)
is invoked.
If $target
is a text, comment, or processing instruction node: content
of $target
is set to $string-value
.
If $target
is a text node that has a parent, upd:removeType(parent($target))
is invoked.
Replaces the existing children of the element node $target
by the optional text node $text
. The attributes of $target
are not affected.
None.
For each node $C
that is a child of $target
, the parent
property of $C
is set to empty.
The parent
property of $text
is set to $target
.
Effects on $target
:
children
is set to consist exclusively of $text
. If $text
is an empty sequence, then $target
has no children.
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.
upd:removeType($target)
is invoked.
Changes the node-name of $target
to $newName
.
$target
must be an element, attribute, or processing instruction node.
If $target
is an element node:
node-name
of $target
is set to $newName
.
upd:removeType($target)
is invoked.
If $newName
has an namespaces
property of $target
, a dynamic error is raised
The namespaces
property of $target
is modified to include a namespace binding derived from $newName
, if this binding did not already exist.
If $target
is an attribute node:
node-name
of $target
is set to $newName
.
upd:removeType($target)
is invoked.
If $newName
is xml:id
, the is-id
property of $target
is set to true
.
If $target
has a parent, and $newName
has an namespaces
property of parent($target)
, a dynamic error is raised
If $target
has a parent, the namespaces
property of parent($target)
is modified to include a namespace binding derived from $newName
, if this binding did not already exist.
If $target
is a processing instruction node, its target
property is set to the local part of $newName
.
At the end of a upd:applyUpdates
.
Merges two
None.
The two
Optionally, upd:mergeUpdates
may raise a dynamic error if any of the following conditions are detected:
Two or more upd:rename
primitives on the merged list have the same target node
Two or more upd:replaceNode
primitives on the merged list have the same target node
Two or more upd:replaceValue
primitives on the merged list have the same target node
Two or more upd:replaceElementContent
primitives on the merged list have the same target node
None.
This routine ends a
Checks the update primitives on $pul
for compatibility. Raises a dynamic error if any of the following conditions are detected:
Two or more upd:rename
primitives on $pul
have the same target node
Two or more upd:replaceNode
primitives on $pul
have the same target node
Two or more upd:replaceValue
primitives on $pul
have the same target node
Two or more upd:replaceElementContent
primitives on $pul
have the same target node
The semantics of all the $pul
are made effective, in the following order:
First, all upd:insertInto
, upd:insertAttributes
, upd:replaceValue
, and upd:rename
primitives are applied.
Next, all upd:insertBefore
, upd:insertAfter
, upd:insertIntoAsFirst
, and upd:insertIntoAsLast
primitives are applied.
Next, all upd:replaceNode
primitives are applied.
Next, all upd:replaceElementContent
primitives are applied.
Finally, all upd:delete
primitives are applied.
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
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.
For each document or element node $top
that was upd:revalidate($top)
is invoked.
If the resulting
For example, a data model constraint violation might occur if multiple attributes with the same parent have the same qualified name (see
The upd:applyUpdates
operation is atomic with respect to the data model. In other words, if upd:applyUpdates
terminates normally, the resulting upd:applyUpdates
raises an error, the resulting
The results of implementation-dependent error conditions such as exceeding resource limits are beyond the scope of this specification.
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.
$top
must be a document node or an element node.
Schema validation is applied to the subtree rooted at $top
in order to recover the types of updated nodes while preserving their
If skip
, upd:revalidate
performs no action. Otherwise:
If lax
, define $topV
as the result of the XQuery expression validate lax {$top}
. If 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.)
This step may raise an error $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
.
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
.
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
.
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.
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.
$N
must be an element or attribute node
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.
If $N
is an element node, its properties are changed as follows:
If type-name
is not equal to xs:untyped
, then
If the parent of type-name
is set to xs:anyType
N
is an element node, then upd:removeType(parent($N))
is invoked.
string-value
is set equal to the concatenated contents of the text node descendants, in document order.
typed-value
is set equal to the string-value
property, as an instance of xs:untypedAtomic
.
The string-value
and/or typed-value
are stored or computed dynamically.
nilled
, is-id
, and is-idrefs
are set to false
.
If $N
is an attribute node, its properties are changed as follows:
type-name
is set to xs:untypedAtomic
.
typed-value
is set equal to the string-value
property, as an instance of xs:untypedAtomic
.
is-id
and is-idrefs
are set to false
.
If $N
has a parent, upd:removeType(parent($N))
is invoked.
The topmost ancestor of $N
is
$N
must be an element or attribute node
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.
If $N
is an element node, its properties are changed as follows:
type-name
is set to xs:untyped
.
typed-value
is set equal to the string-value
property, as an instance of xs:untypedAtomic
.
The string-value
and/or typed-value
are stored or computed dynamically.
nilled
, is-id
, and is-idrefs
are set to false
.
upd:setToUntyped()
is invoked on the attributes and child element nodes of $N
.
If $N
is an attribute node, its properties are changed as follows:
type-name
is set to xs:untypedAtomic
.
typed-value
is set equal to the string-value
property, as an instance of xs:untypedAtomic
.
is-id
and is-idrefs
are set to false
.
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
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
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
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.
The static semantics is specified through a
The judgment
holds when, in the static environment statEnv, the
expression
The static environment is the same as the one defined in
statEnv.revalidationMode |
|
We extend the
XQuery Core defined in
The core grammar production for IfExpr
can be found in
The core grammar production for OrExpr
can be found in
The core grammar production for FLWORExpr
can be found in
The core grammar production for QuantifiedExpr
can be found in
The core grammar production for TypeswitchExpr
can be found in
The core grammar production for VarName
can be found in
In addition to the normalization rules defined in
Revalidation declarations are left unchanged through normalization.
The revalidation declaration modifies the revalidation mode in the static context.
In addition to the normalization and static typing rules
defined in
The following normalization rules applies to insert expressions. Note that whether the expression is written using the 'nodes' or 'node' modifier, the normalized expression always uses the 'nodes' modifier.
item-sequence-to-node-sequence
(Where item-sequence-to-node-sequence
is the special function used
for computing element content and is defined in
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.
empty
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.
empty
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.
The static typing rule for delete is as follows.
empty
The following normalization rules applies to replace expressions.
item-sequence-to-node-sequence
(Normalization of replace value of expressions.
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.
empty
An element, text, comment, or processing instruction node can be replaced only by zero or more element, text, comment, or processing instruction nodes.
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.
empty
The following normalization rule applies to rename expressions.
fn:data
(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
.
xs:QName
| xs:string
| xs:untypedAtomic
)empty
The following normalization rule applies to transform expressions.
copy |
item-sequence-to-node-sequence ( |
... |
item-sequence-to-node-sequence ( |
modify |
The transform expression is type checked using the following inference rule.
copy |
|
... |
|
modify |
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 may 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
The EBNF in this document and in this section is aligned with
the current XML Query 1.0 grammar (see
The following symbols are used only in the definition of
terminal symbols; they are not terminal symbols in the
grammar of
The following items in this specification are implementation-defined:
The revalidation modes that are supported by this implementation.
The default revalidation mode for this implementation.
Whether the implementation raises dynamic error
The mechanism (if any) by which an external function can return an XDM instance and/or a pending update list to the invoking query.
The semantics of fn:put()
, including the kinds of nodes accepted as operands by this function.
It is a static error if an
The topmost expression in the body of a query.
The modify
clause of a transform expression.
The return
clause of a FLWOR expression.
The return
clauses of a typeswitch expression in which every return
clause contains an ( )
, or a call to the fn:error
function.
The then
and else
clauses of a conditional statement in which both the then
and else
clauses contain either an ( )
, or a call to the fn:error
function.
An operand of a comma expression in which each operand is either an ( )
, or a call to the fn:error
function.
The content of a parenthesized expression.
The body of a function declaration in which the keyword updating
is specified.
It is a static error if an ( )
or a call to the fn:error
function is used in one of the following positions:
The modify
clause of a transform expression.
The top-level expression in the body of a function declaration in which the keyword updating
is specified.
It is a static error if a Prolog contains more than one revalidation declaration.
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.
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.
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.
It is a type error if the target expression of a delete expression does not return a sequence of zero or more nodes.
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.
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.
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.
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.
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.
In a transform expression, it is a type error if a source expression in the copy
clause does not return a single node.
In a transform expression, it is a dynamic error if the modify
clause modifies any node that was not created by the copy
clause.
It is a dynamic error if any node is the target of more than one rename
expression within the same query.
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.
It is a dynamic error if any node is the target of more than one replace value of
expression within the same query.
It is a dynamic error if a function that was declared to be external
but not updating
returns a non-empty pending update list.
It is a dynamic error if a function that was declared to be both external
and updating
returns a non-empty data model instance.
An implementation may (but is not required to) raise a dynamic error if a node is deleted that had no parent before execution of the query began.
It is a dynamic error if the
It is a type error if an insert expression specifies the insertion of an attribute node into a document node.
It is a dynamic error if an insert, replace, or rename expression affects an element node by introducing a new namespace binding that
It is a dynamic error if the effect of a set of updating expressions is to introduce
It is a dynamic error if the target of a rename expression is a processing instruction node, and the new name expression returns a QName with a non-empty namespace prefix.
It is a static error if a revalidation declaration in a Prolog specifies a revalidation mode that is not supported by the current implementation.
It is a dynamic error if the target expression of an insert, replace, or rename expression evaluates to an empty sequence.
It is a static error if a function declaration specifies both updating
and a return type.
In an insert expression where before
or after
is specified, it is a dynamic error if node returned by the target expression does not have a parent.
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.
It is a dynamic error if the first operand of fn:put
is not a node of a supported kind.
It is a dynamic error if the second operand of fn:put
is not a valid lexical representation of the xs:anyURI
type.
It is a dynamic error if a constructor or replace expression would result in a processing instruction node whose content includes the string "?>
".
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.
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.)
The XML Schema specified in this appendix accomplishes its integration by importing
the XML Schema defined for XQueryX in
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.
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
The following example is based on the data and queries in the use cases
in
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
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
Application of the stylesheet in
In
The insertAttribute
, replaceValue
, and rename
primitives do not conflict with any
other primitives, and can be applied at any time.
insertInto
primitives must be applied before insertIntoAsFirst/Last
and
insertBefore/After
primitives. Reason: if an unpositioned insert were applied after a
positioned insert, it might interfere with the position established by the earlier positioned insert. For example, suppose node A is inserted "before" node B. A later unpositioned insert into the common parent of A and B might intervene between A and B, which is not allowed by the semantics of "insert before."
insertBefore/After
primitives must be applied before replaceNode
primitives. Reason: After a node
has been replaced, it no longer has a parent, so "before" and "after" the replaced node
are no longer defined.
insertIntoAsFirst/Last
primitives must be applied before replaceElementContent
primitives. Reason:
this was a decision of the working group. The intent of this decision is that, if both of these primitives are applied to the same target node in a query, the effective result is determined by the replaceElementContent
primitive.
replaceNode
primitives must be applied before replaceElementContent
primitives. Reason: if element
content that includes a node N has been replaced, then N no longer has a parent. In this case,
"replace node N" is undefined.
replaceNode
primitives must be applied before delete
primitives. Reason: After a node has been
deleted, it no longer has a parent. Replacing a node that has no parent is undefined.
This log records the substantive changes that have been made to this document since the Initial Working Draft of 27 January 2006. Minor editorial changes are not included in this log.
Grammar changes:
Add do
as initial keyword in InsertExpr, DeleteExpr, ReplaceExpr, RenameExpr.
Eliminate curly braces around first operands of all updating expressions (as a result, DirectConstructor is no longer a special case in InsertExpr).
Eliminate do
keyword from FLWOR and typeswitch expressions (any updating
subexpressions must be in the return
clause).
In TransformExpr, change do
keyword to modify
, and change
ExprSingle to Expr in modify-clause.
In ReplaceExpr, keep only a single action-clause (earlier syntax allowed one or more action-clauses).
In RenameExpr, change to
keyword to as
(avoids an ambiguity).
A comma expression no longer permits its operands to include a mixture of updating and non-updating expressions.
In a function declaration, if updating
is specified, the function does not return a value, and no result type may be declared.
Added clarifying details:
It is a static error if the operand expression of a typeswitch is an updating expression.
if (text) then ( ) else ( )
is a non-updating expression.
An empty parenthesized expression ( )
is a non-updating expression.
The body of an updating function may contain an empty expression ( )
or a call to the fn:error
function.
Specified that upd:applyUpdates
is an atomic operation with respect to the data model, but that propagation of data model changes to an underlying physical representation is beyond the
scope of this specification.
Eliminated the incompatibility between primitive operations insert into
and insert into as last
when these operations are applied to the same target node.
Replaced all occurrences of the xdt
: namespace prefix with xs:
, following a joint decision by the Query and XSLT Working Groups.
Simplification of the rules for compatibility of updating expressions. Creates three new update primitives: upd:insertAsFirst
, upd:replaceNode,
and upd:replaceValue
. Eliminates the compatibility table and introduces new mappings of XQuery updating expressions onto update primitives as suggested in http://lists.w3.org/Archives/Member/member-query-ultf/2006Mar/0028.html. Introduces new definition of upd:applyUpdates
, removing many incompatibilities.
More specific definition of the upd:revalidate
update operation.
More formal definitions of updating and non-updating expressions.
Corrections to error XUST0001 (formerly XUST0101) and definition of a new error XUST0002.
Define replacement of a node as substitution of new nodes in the position of the original node. As a result, an attribute node can be replaced only by attribute nodes, and content (element, text, comment, and PI) nodes can be replaced only by content nodes.
Revised the mappings of replace
expressions onto underlying primitives to make the compatibility rules more consistent. The new mappings require one new update primitive, called upd:replaceElementContent
, which is applied immediately before the final deletion of nodes.
Created new subheadings inside the "Replace" section to call attention to the two forms of a replace expression (editorial change).
Added the function fn:put
for storing a document or element to a location.
Clarified the semantics of node deletion: the deleted node is detached from its parent. If the node to be deleted has no parent, no change is made to the data model instance, and it is implementation-defined whether an error is raised. Node deletions have no effect on variable bindings or available documents and collections within the current snapshot. Affected sections: 2.3.2 (Delete), 3.2.2 (upd:applyUpdates).
Added a rule that each variable binding in the copy clause of a transform statement must create exactly one copied node.
Simplified the description of fn:put
, eliminating one signature and two error conditions.
Semantics of fn:put
are implementation-defined and occur after completion of the current snapshot.
Clarified result when the value of a node is replaced by an empty sequence.
Corrected error in upd:replaceNode, Rule 3a, regarding replacement of attribute nodes (attributes that were not replaced remain unaffected.)
Clarified that it is not an error to insert zero nodes (the insertion list may be empty.)
Added a new error code [err:XUDY0022] for the case in which a user attempts to insert an attribute node as a child of a document node.
In Section 3.1.9 (upd:replaceValue), clarified what happens when the target is
a text node that has no parent.
(Value is replaced, no error is raised, upd:removeType
is not invoked.)
In Section 3.1.11 (upd:rename), clarified what happens when the target is an attribute node that has no parent. (Node is renamed, no error is raised.)
In Section 2.3.1 (Insert), changed semantic rule 2 to allow the target node to be a text,
comment, or PI node when before
or after
is specified.
Also affects error code err:XUTY0006.
Clarified the effects of insert, replace, and rename expressions on namespace bindings. The main points are (1) these expressions may not introduce namespace conflicts (the same namespace prefix bound to two or more different namespace URIs within the scope of a single element; (2) the effects of a rename expression are limited to a single target node and do not affect the descendants of the target node; and (3) new error codes XUDY0023 and XUDY0024.
In Section 3.2.2 (upd:applyUpdates), added an example of how a global data model constraint might be violated.
In Section 2.4.3 (Conditional Expression), added a rule that the if-clause may not contain an updating expression. (This rule was intended but overlooked in previous drafts.) Closes Bug 3798.
In Section 2.3.3.2 (Replacing the Value of a Node), edited semantic rule 4
to raise an error if an updated comment node ends with a hyphen
or contains two adjacent hyphens, or if an updated PI node contains the string "?>
".
Results in amendments to error codes XQDY0026 and XQDY0072.
In Section 3.2.2 (upd:applyUpdates), added a new semantic rule that
deletes empty text nodes from the children
property of
any element node after all updates have been applied. Closes Bug 4313.
In Section 2.1 (Extensions to the Processing Model), stated that propagation of XDM updates to an underlying persistent store is beyond the scope of the current specification. Also, in Section 3.2.2 (upd:applyUpdates), stated in Rule 7 that atomicity is guaranteed only with respect to error conditions specified in this document. Together, these changes close Bug 4168.
In Section 2.5 (Extensions to Built-in Function Library), specified that the
return type of fn:put()
is empty-sequence()
.
In Section 2.3.4 (Rename), specified a dynamic error [err:XUDY0025] if the new name of a processing instruction node includes a non-empty namespace prefix. Closes Bug 4169.
Made support for each of the three revalidation modes implementation-defined, and added a static error [err:XUDY0026]) for specifying an unsupported revalidation mode. Closes Bug 4287.
Removed all references to "marking a node for deletion." Sections affected: upd:delete, upd:replaceNode, and upd:applyUpdates. This change simplifies the description of the update primitives without changing the result of any query.
Added revised definitions for existing error codes XQDY0026, XQDY0072, and XQDY0074 (these errors can now be raised by updating expressions.)
Added better definitions for "updating expression," "snapshot," and "node identity".
Removed a redundant definition of compatibility of updating expressions (Section 2.4.6 now refers to Section 3.2.2 for the normative definition.)
Added a rule that the initializing expression in a variable declaration must be a non-updating expression.
Added parentheses to example in Section 2.5.4 (Comma Expression). Closes Bug 3799.
Reorganized error codes relating to the target of an updating expression, reducing the amount of static checking that is required. Codes XUTY0005, XUTY0006, XUTY0007, XUTY0008, XUTY0010, XUTY0011, and XUTY0012 are type errors. Codes XUDY0009, XUDY0022, XUDY0023, XUDY0025, XUDY0027, XUDY0029, XQDY0026, and XQDY0072 are dynamic errors. Closes Bug 4526.
Added requirements relating to preserving the relative order and adjacency of inserted nodes. Closes Bugs 4527, 4528, 4529, and 4574.
Added a new error code [XUST0028] for an updating function declaration that specifies a return type. Closes Bug 4611.
Split the former error code XUTY0006 into a type error XUTY0006 and a dynamic error XUDY0029. Also split the former error code XUDY0022 into a type error XUTY0022 and a dynamic error XUDY0030.
Deleted the keyword transform
from the syntax of a transform expression.
Closes Bug 4540.
Modified the grammar to eliminate the do
keyword from all
updating expressions and to add the keyword node
or nodes
to these expressions. This change affects many sections of the document.
Added a new Section 4 describing the Static Typing Feature for updating expressions.
Added a new Appendix listing the implementation-defined items introduced by the XQuery Update Facility.
Added a new Appendix documenting the reasons for the order in which update primitives are applied when processing a pending update list.
Added a new Appendix specifying XQueryX syntax for updating expressions.