This section describes the update operations defined by XQuery Update Facility 3.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.
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.
upd:insertBefore( $target as node(), $content as node()+)
Inserts $content
immediately before $target
.
$target
must be an element, text, processing
instruction, or comment node with a non-empty parent
property. $content
must be a sequence containing only element, text, processing instruction,
and comment nodes.
Effects on nodes in $content
:
For each node in $content
, the parent
property is set to parent($target)
.
If the type-name
property of parent($target)
is 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.
All the namespace bindings of parent($target)
are marked for namespace propagation.
upd:insertAfter( $target as node(), $content as node()+)
Inserts $content
immediately after $target
.
$target
must be an element, text, processing
instruction, or comment node with a non-empty parent
property. $content
must be a sequence containing only element, text, processing instruction,
and comment nodes.
The semantics of upd:insertAfter
are identical to the semantics of upd:insertBefore
, except that Rule 2a is changed as follows:
The children
property of parent($target)
is modified to add the nodes in $content
just after $target
, preserving their order.
upd:insertInto( $target as node(), $content as node()+)
Inserts $content
as the children of $target
, in an implementation-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 add the nodes in $content
in implementation-dependent positions, preserving their relative order.
upd:insertIntoAsFirst( $target as node(), $content as node()+)
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 add the nodes in $content
as the first children, preserving their order.
upd:insertIntoAsLast( $target as node(), $content as node()+)
Inserts $content
as the last children of $target
.
$target
must be an element or document node. $content
must be a sequence containing only element, text, processing instruction,
and comment nodes.
The semantics of upd:insertIntoAsLast
are identical to the semantics of upd:insertBefore
, except that $target
is 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.
upd:insertAttributes( $target as element(), $content as attribute()+)
Inserts $content
as attributes of $target
.
None
For each node $A
in $content
:
The parent
property of $A
is set to $target
.
If the type-name
property of $target
is xs:untyped
, then upd:setToUntyped($A)
is invoked.
The following properties of $target
are changed:
attributes
: Modified to add the nodes in $content
.
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.
upd:removeType($target)
is invoked.
upd:delete( $target as node())
None
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.
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.
upd:replaceNode( $target as node(), $replacement as node()*)
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.
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 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 add namespace bindings for any attribute namespace prefixes in $replacement
that did not already have bindings. These bindings are marked for namespace propagation.
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.
If $target
or any node in $replacement
is an element, attribute, or text
node, upd:removeType(parent($target))
is invoked.
upd:replaceValue( $target as node(), $string-value as xs:string)
Replaces the string value of $target
with $string-value
.
$target
must be an attribute, text, comment, or processing instruction node.
If $target
is an attribute node:
string-value
of $target
is set to $string-value
.
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.
upd:replaceElementContent( $target as element(), $text as text()?)
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.
upd:rename( $target as node(), $newName as xs:QName)
Changes the node-name of $target
to $newName
.
$target
must be an element, attribute, or processing instruction node.
If $target
is an element node:
node-name
of $target
is set to $newName
.
upd:removeType($target)
is invoked.
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.
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.
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, 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.
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
.
upd:put( $node as node(), $uri as xs:string, $params as element(output:serialization-parameters))
The XDM node tree rooted at $node
is stored to the location specified by $uri
.
$uri
must be a valid absolute URI.
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.
An implementation that uses serialization when storing the node MUST use the serialization parameters identified by $params
.
upd:compatibilityCheck( $pul as pending-update-list)
Performs compatibility checking against a pending update list, raising errors if problems are found.
None.
A dynamic error if any of the following conditions are detected:
Two or more upd:rename
primitives in $pul
have the same target node [err:XUDY0015].
Two or more upd:replaceNode
primitives in $pul
have the same target node [err:XUDY0016].
Two or more upd:replaceValue
primitives in $pul
have the same target node [err:XUDY0017].
Two or more upd:replaceElementContent
primitives in $pul
have the same target node [err:XUDY0017].
Two or more upd:put
primitives in $pul
have the same $uri
operand [err:XUDY0031].
Two or more primitives in $pul
create conflicting namespace bindings for the same element node [err:XUDY0024]. The following kinds of primitives create namespace bindings:
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
.
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
.
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
.
upd:mergeUpdates( $pul1 as pending-update-list, $pul2 as pending-update-list)
Merges two pending update lists.
None.
The two pending update lists are merged and a single pending update list containing all the update primitives from both lists. The resulting pending update list is returned.
Optionally, upd:compatibilityCheck may be executed against the resulting pending update list.
upd:applyUpdates( $pul as pending-update-list, $revalidation-mode as xs:string, $inherit-namespaces as xs:boolean)
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.
$revalidation-mode
must be "strict"
, "lax"
, or "skip"
Checks the update primitives on $pul
for compatibility using
upd:compatibilityCheck.
The semantics of all update primitives on $pul
, other than upd:put
primitives, 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.
Next, 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 node identity of the resulting text node is implementation-dependent.
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.
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 and XPath Data Model (XDM) 3.0], 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.
If $inherit-namespaces
is true
, then upd:propagate-namespace($element, $prefix, $uri)
is invoked
for each namespace binding that was marked for namespace propagation, 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.
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.
As the final step, all upd:put
primitives on $pul
are applied.
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.
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.
upd:revalidate( $top as node(), $revalidation-mode as xs:string)
$top
must be a document node or an element node.
$revalidation-mode
must be "strict"
, "lax"
, or "skip"
.
Schema validation is applied to the subtree rooted at $top
in order to recover the types of updated nodes while preserving their node identities.
If $revalidation-mode
is skip
, upd:revalidate
performs no action. Otherwise:
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]XQ30 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
.
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.
Note:
After revalidation, the type annotations of the nodes in the validated subtree are consistent with their content. It is expected that implementations will optimize the revalidation process by taking into account which nodes have been modified since they were last validated.
upd:removeType( $N as node())
$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
type-name
is set to xs:anyType
If the parent of 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
.
Note:
The data model allows some flexibility to implementations regarding whether string-value
and/or typed-value
are stored or computed dynamically.
nilled
, is-id
, and is-idrefs
are set to false
.
If $N
is an attribute node, its properties are changed as follows:
type-name
is set to 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 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.
upd:setToUntyped( $N as node())
$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
.
Note:
The data model allows some flexibility to implementations regarding whether string-value
and/or typed-value
are stored or computed dynamically.
nilled
, is-id
, and is-idrefs
are set to false
.
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-idrefs
is set to false
.
is-id
is set to false
if the attribute name is not xml:id
.
upd:propagateNamespace( $element as element(), $prefix as xs:NCName, $uri as xs:anyURI)
None
Propagates a namespace binding to all descendants of an element.
For each element $child
among the children of $element
that does not have a namespace binding for $prefix
,
add a namespace binding ($prefix, $uri)
to $child
call upd:propagateNamespace($child, $prefix, $uri)