8 Update Operations

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.

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

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

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

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

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

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

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

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

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

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

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

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

8.1.12 upd:put

Parameters
upd:put(
   $node as node(),
   $uri as xs:string,
   $params as element(output:serialization-parameters))
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.

An implementation that uses serialization when storing the node MUST use the serialization parameters identified by $params.

8.2 Update Routines

8.2.1 upd:compatibilityCheck

Parameters
upd:compatibilityCheck(
   $pul as pending-update-list)
Summary

Performs compatibility checking against a pending update list, raising errors if problems are found.

Constraints

None.

Semantics

A dynamic error if any of the following conditions are detected:

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

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

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

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

  5. Two or more upd:put primitives in $pul have the same $uri operand [err:XUDY0031].

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

    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.

    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.

    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.

8.2.2 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. The resulting pending update list is returned.

  2. Optionally, upd:compatibilityCheck may be executed against the resulting pending update list.

8.2.3 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 using upd:compatibilityCheck.

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

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

  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.

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

  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.

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

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

8.2.7 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)