Please check the errata for any errors or issues reported since publication.
See also translations.
This document is also available in these non-normative formats: Specification in XML format and XML function catalog.
Copyright © 2000 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
This document defines constructor functions, operators, and functions on the datatypes defined in [XML Schema Part 2: Datatypes Second Edition] and the datatypes defined in [XQuery and XPath Data Model (XDM) 3.1]. It also defines functions and operators on nodes and node sequences as defined in the [XQuery and XPath Data Model (XDM) 3.1]. These functions and operators are defined for use in [XML Path Language (XPath) 4.0] and [XQuery 4.0: An XML Query Language] and [XSL Transformations (XSLT) Version 4.0] and other related XML standards. The signatures and summaries of functions defined in this document are available at: http://www.w3.org/2005/xpath-functions/.
A summary of changes since version 3.1 is provided at G Changes since 3.1.
This version of the specification is work in progress. It is produced by the QT4 Working Group, officially the W3C XSLT 4.0 Extensions Community Group. Individual functions specified in the document may be at different stages of review, reflected in their History notes. Comments are invited, in the form of GitHub issues at https://github.com/qt4cg/qtspecs.
The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).
The following functions take function items as an argument.
| Function | Meaning |
|---|---|
fn:apply | Makes a dynamic call on a function with an argument list supplied in the form of an array. |
fn:chain | Applies a sequence of functions starting with an initial input. |
fn:do-until | Processes a supplied value repeatedly, continuing when some condition is false, and returning the value that satisfies the condition. |
fn:every | Returns true if every item in the input sequence matches a supplied predicate. |
fn:filter | Returns those items from the sequence $input for which the supplied function $predicate returns true. |
fn:fold-left | Processes the supplied sequence from left to right, applying the supplied function repeatedly to each item in turn, together with an accumulated result value. |
fn:fold-right | Processes the supplied sequence from right to left, applying the supplied function repeatedly to each item in turn, together with an accumulated result value. |
fn:for-each | Applies the function item $action to every item from the sequence $input in turn, returning the concatenation of the resulting sequences in order. |
fn:for-each-pair | Applies the function item $action to successive pairs of items taken one from $input1 and one from $input2, returning the concatenation of the resulting sequences in order. |
fn:highest | Returns those items from a supplied sequence that have the highest value of a sort key, where the sort key can be computed using a caller-supplied function. |
fn:index-where | Returns the positions in an input sequence of items that match a supplied predicate. |
fn:lowest | Returns those items from a supplied sequence that have the lowest value of a sort key, where the sort key can be computed using a caller-supplied function. |
fn:partial-apply | Performs partial application of a function item by binding values to selected arguments. |
fn:partition | Partitions a sequence of items into a sequence of non-empty arrays containing the same items, starting a new partition when a supplied condition is true. |
fn:scan-left | Produces the sequence of successive partial results from the evaluation of fn:fold-left with the same arguments. |
fn:scan-right | Produces the sequence of successive partial results from the evaluation of fn:fold-right with the same arguments. |
fn:some | Returns true if at least one item in the input sequence matches a supplied predicate. |
fn:sort | Sorts a supplied sequence, based on the value of a number of sort keys supplied as functions. |
fn:sort-with | Sorts a supplied sequence, according to the order induced by the supplied comparator functions. |
fn:subsequence-where | Returns a contiguous sequence of items from $input, with the start and end points located by applying predicates. |
fn:take-while | Returns items from the input sequence prior to the first one that fails to match a supplied predicate. |
fn:transitive-closure | Returns all the nodes reachable from a given start node by applying a supplied function repeatedly. |
fn:while-do | Processes a supplied value repeatedly, continuing while some condition remains true, and returning the first value that does not satisfy the condition. |
With all these functions, if the caller-supplied function fails with a dynamic error, this error is propagated as an error from the higher-order function itself.
Processes the supplied sequence from left to right, applying the supplied function repeatedly to each item in turn, together with an accumulated result value.
fn:fold-left( | ||
$input | as , | |
$accuminit | as , | |
$action | as | |
) as | ||
This function is deterministic, context-independent, and focus-independent.
If $input is empty, the function returns $accuminit.
If $input contains at least one item, the function calls $action($accuminit, $input[1]), returning a value A1.
If $input contains a second item, the function then calls $action(A1, $input[2]), returning A2; to process the nth item it calls $action(An-1, $input[N]).
This continues in the same way until the end of the $input sequence; the final result is the result of the last call on $action.
The function delivers the same result as the following XQuery implementation.
declare function fold-left(
$input as item()*,
$accum as item()*,
$action as function(item()*, item()) as item()*
) as item()* {
if (empty($input))
then $accum
else fold-left(tail($input), $action($accum, head($input)), $action)
};declare function fold-left(
$input as item()*,
$init as item()*,
$action as function(item()*, item()) as item()*
) as item()* {
if (empty($input))
then $init
else fold-left(tail($input), $action($init, head($input)), $action)
};As a consequence of the function signature and the function calling rules, a type error occurs if the supplied function $action cannot be applied to two arguments, where the first argument is either the value of $accuminit or the result of a previous application of $action, and the second is any single item from the sequence $input.
This operation is often referred to in the functional programming literature as “folding” or “reducing” a sequence. It typically takes a function that operates on a pair of values, and applies it repeatedly, with an accumulated result as the first argument, and the next item in the sequence as the second argument. The accumulated result is initially set to the value of the $accuminit argument, which is conventionally a value (such as zero in the case of addition, one in the case of multiplication, or a zero-length string in the case of string concatenation) that causes the function to return the value of the other argument unchanged.
Unlike other functions that apply a user-supplied callback function to successive items in a sequence, this function does not supply the current position to the callback function as an optional argument. If positional information is required, this can be achieved by first forming the sequence $input ! {'position': position(), 'item': .} and then applying the fn:fold-left function to this sequence.
| Expression: | fold-left(
1 to 5,
0,
fn($a, $b) { $a + $b }
) |
|---|---|
| Result: | 15 (This returns the sum of the items in the sequence). |
| Expression: | fold-left(
(2, 3, 5, 7),
1,
fn($a, $b) { $a * $b }
) |
| Result: | 210 (This returns the product of the items in the sequence). |
| Expression: | fold-left(
(true(), false(), false()),
false(),
fn($a, $b) { $a or $b }
) |
| Result: | true() (This returns |
| Expression: | fold-left(
(true(), false(), false()),
false(),
fn($a, $b) { $a and $b }
) |
| Result: | false() (This returns |
| Expression: | fold-left(
1 to 5,
(),
fn($a, $b) { $b, $a }
) |
| Result: | 5, 4, 3, 2, 1 (This reverses the order of the items in a sequence). |
| Expression: | fold-left( 1 to 5, "", concat(?, ".", ?) ) |
| Result: | ".1.2.3.4.5" |
| Expression: | fold-left(
1 to 5,
"$z",
concat("$f(", ?, ", ", ?, ")")
) |
| Result: | "$f($f($f($f($f($z, 1), 2), 3), 4), 5)" |
| Expression: | fold-left(
1 to 5,
{},
fn($map, $n) { map:put($map, $n, $n * 2) }
) |
| Result: | { 1: 2, 2: 4, 3: 6, 4: 8, 5: 10 } |
Processes the supplied sequence from right to left, applying the supplied function repeatedly to each item in turn, together with an accumulated result value.
fn:fold-right( | ||
$input | as , | |
$accuminit | as , | |
$action | as | |
) as | ||
This function is deterministic, context-independent, and focus-independent.
If $input is empty, the function returns $accuminit.
Let In be the last item in $input, and let An be $accuminit. The function starts by calling $action(In, $accuminit), producing a result An-1.
If there is a previous item, In-1, the function then calls $action(In-1, An-1), producing the result An-2.
This continues in the same way until the start of the $input sequence is reached; the final result is the value A0.
The function delivers the same result as the following XQuery implementation.
declare function fold-right(
$input as item()*,
$accum as item()*,
$action as function(item(), item()*) as item()*
) as item()* {
if (empty($input))
then $accum
else $action(head($input), fold-right(tail($input), $accum, $action))
};declare function fold-right(
$input as item()*,
$init as item()*,
$action as function(item(), item()*) as item()*
) as item()* {
if (empty($input))
then $init
else $action(head($input), fold-right(tail($input), $init, $action))
};As a consequence of the function signature and the function calling rules, a type error occurs if the supplied function $action cannot be applied to two arguments, where the first argument is any item in the sequence $input, and the second is either the value of $accuminit or the result of a previous application of $action.
This operation is often referred to in the functional programming literature as “folding” or “reducing” a sequence. It takes a function that operates on a pair of values, and applies it repeatedly, with the next item in the sequence as the first argument, and the result of processing the remainder of the sequence as the second argument. The accumulated result is initially set to the value of the $accuminit argument, which is conventionally a value (such as zero in the case of addition, one in the case of multiplication, or a zero-length string in the case of string concatenation) that causes the function to return the value of the other argument unchanged.
In cases where the function performs an associative operation on its two arguments (such as addition or multiplication), fn:fold-right produces the same result as fn:fold-left.
Unlike other functions that apply a user-supplied callback function to successive items in a sequence, this function does not supply the current position to the callback function as an optional argument. If positional information is required, this can be achieved by first forming the sequence $input ! {'position': position(), 'item': .} and then applying the fn:fold-right function to this sequence.
| Expression: | fold-right(
1 to 5,
0,
fn($a, $b) { $a + $b }
) |
|---|---|
| Result: | 15 (This returns the sum of the items in the sequence). |
| Expression: | fold-right( 1 to 5, "", concat(?, ".", ?) ) |
| Result: | "1.2.3.4.5." |
| Expression: | fold-right(
1 to 5,
"$z",
concat("$f(", ?, ", ", ?, ")")
) |
| Result: | "$f(1, $f(2, $f(3, $f(4, $f(5, $z)))))" |
Produces the sequence of successive partial results from the evaluation of fn:fold-left with the same arguments.
fn:scan-left( | ||
$input | as , | |
$accuminit | as , | |
$action | as | |
) as | ||
This function is deterministic, context-independent, and focus-independent.
The function returns a sequence of N+1 single-member arraysDM, where N is the number of items in $input. For values of $n in the range 0 to N, the value of the single member of array $n+1 in the result sequence is the value of the expression fold-left( subsequence($input, 1, $n), $accuminit, $action ).
The effect of the function is equivalent to the result of the following XPath expression.
(0 to count($input))
! [fold-left( subsequence($input, 1, .), $accum, $action )](0 to count($input))
! [fold-left( subsequence($input, 1, .), $init, $action )]A practical implementation is likely to compute each array in the result sequence based on the value of the previous item, rather than computing each item independently as implied by the specification.
| Expression: | scan-left(1 to 5, 0, op('+')) |
|---|---|
| Result: | [ 0 ], [ 1 ], [ 3 ], [ 6 ], [ 10 ], [ 15 ] |
| Expression: | scan-left(1 to 3, 0, op('-')) |
| Result: | [ 0 ], [ -1 ], [ -3 ], [ -6 ] |
| Expression: | scan-left(1 to 5, 1, op('*')) |
| Result: | [ 1 ], [ 1 ], [ 2 ], [ 6 ], [ 24 ], [ 120 ] |
| Expression: | scan-left(1 to 3, (), fn($a, $b) { $b, $a }) |
| Result: | [ () ], [ 1 ], [ (2, 1) ], [ (3, 2, 1) ] ] |
Produces the sequence of successive partial results from the evaluation of fn:fold-right with the same arguments.
fn:scan-right( | ||
$input | as , | |
$accuminit | as , | |
$action | as | |
) as | ||
This function is deterministic, context-independent, and focus-independent.
The function returns a sequence of N+1 single-member arraysDM, where N is the number of items in $input. For values of $n in the range 0 to N, the value of the single member of array $n+1 in the result sequence is the value of the expression fold-right( subsequence($input, count($input)-$n+1), $accuminit, $action ).
The effect of the function is equivalent to the result of the following XPath expression.
(0 to count($input))
! [fold-right( subsequence($input, count($input)-.+1), $accum, $action )](0 to count($input))
! [fold-right( subsequence($input, count($input)-.+1), $init, $action )]A practical implementation is likely to compute each array in the result sequence based on the value of the previous item, rather than computing each item independently as implied by the specification.
| Expression: | scan-right(1 to 10, 0, op('+')) |
|---|---|
| Result: | [ 55 ], [ 54 ], [ 52 ], [ 49 ], [ 45 ], [ 40 ], [ 34 ], [ 27 ], [ 19 ], [ 10 ], [ 0 ] |
| Expression: | scan-right(1 to 3, 0, op('-')) |
| Result: | [ 2 ], [ -1 ], [ 3 ], [ 0 ] |
| Expression: | scan-right(1 to 5, (), fn($a, $b) { $b, $a }) |
| Result: | [(5,4,3,2,1)], [(5,4,3,2)], [(5,4,3)], [(5,4)], [5], [()] |
Arrays were introduced as a new datatype in XDM 3.1. This section describes functions that operate on arrays.
An array is an additional kind of item. An array of size N is a mapping from the integers (1 to N) to a set of values, called the members of the array, each of which is an arbitrary sequence. Because an array is an item, and therefore a sequence, arrays can be nested.
An array acts as a function from integer positions to associated values, so the function call $array($index) can be used to retrieve the array member at a given position. The function corresponding to the array has the signature function($index as xs:integer) as item()*. The fact that an array is a function item allows it to be passed as an argument to higher-order functions that expect a function item as one of their arguments.
The functions defined in this section use a conventional namespace prefix array, which is assumed to be bound to the namespace URI http://www.w3.org/2005/xpath-functions/array.
As with all other values, arrays are treated as immutable. For example, the array:reverse function returns an array that differs from the supplied array in the order of its members, but the supplied array is not changed by the operation. Two calls on array:reverse with the same argument will return arrays that are indistinguishable from each other; there is no way of asking whether these are “the same array”. Like sequences, arrays have no identity.
All functionality on arrays is defined in terms of two primitives:
The function array:members decomposes an array to a sequence of value records.
The function array:of-members composes an array from a sequence of value records.
A value record here is an item that encapsulates an arbitrary value; the representation chosen for a value record is record(value as item()*), that is, a map containing a single entry whose key is the string "value" and whose value is the encapsulated sequence.
| Function | Meaning |
|---|---|
array:append | Returns an array containing all the members of a supplied array, plus one additional member at the end. |
array:build | Returns an array obtained by evaluating the supplied function once for each item in the input sequence. |
array:empty | Returns true if the supplied array contains no members. |
array:filter | Returns an array containing those members of the $array for which $predicate returns true. A return value of () is treated as false. |
array:flatten | Replaces any array appearing in a supplied sequence with the members of the array, recursively. |
array:fold-left | Evaluates the supplied function cumulatively on successive members of the supplied array. |
array:fold-right | Evaluates the supplied function cumulatively on successive values of the supplied array. |
array:foot | Returns the last member of an array. |
array:for-each | Returns an array whose size is the same as array:size($array), in which each member is computed by applying $action to the corresponding member of $array. |
array:for-each-pair | Returns an array obtained by evaluating the supplied function once for each pair of members at the same position in the two supplied arrays. |
array:get | Returns the value at the specified position in the supplied array (counting from 1). |
array:head | Returns the first member of an array, that is $array(1). |
array:index-of | Returns a sequence of positive integers giving the positions within the array $array of members that are equal to $target. |
array:index-where | Returns the positions in an input array of members that match a supplied predicate. |
array:insert-before | Returns an array containing all the members of the supplied array, with one additional member at a specified position. |
array:items | Returns the sequence concatenation of the members of an array. |
array:join | Concatenates the contents of several arrays into a single array, with an optional separator between adjacent members. |
array:members | Delivers the contents of an array as a sequence of value records. |
array:of-members | Constructs an array from the contents of a sequence of value records. |
array:put | Returns an array containing all the members of a supplied array, except for one member which is replaced with a new value. |
array:remove | Returns an array containing all the members of the supplied array, except for the members at specified positions. |
array:reverse | Returns an array containing all the members of a supplied array, but in reverse order. |
array:size | Returns the number of members in the supplied array. |
array:slice | Returns an array containing selected members of a supplied input array based on their position. |
array:sort | Sorts a supplied array, based on the value of a number of sort keys supplied as functions. |
array:split | Delivers the contents of an array as a sequence of single-member arrays. |
array:subarray | Returns an array containing all members from a supplied array starting at a supplied position, up to a specified length. |
array:tail | Returns an array containing all members except the first from a supplied array. |
array:trunk | Returns an array containing all members except the last from a supplied array. |
Evaluates the supplied function cumulatively on successive members of the supplied array.
array:fold-left( | ||
$array | as , | |
$accuminit | as , | |
$action | as | |
) as | ||
This function is deterministic, context-independent, and focus-independent.
The function is defined formally below, in terms of the equivalent fn:fold-left function for sequences.
The effect of the function is equivalent to the result of the following XPath expression.
fold-left(
array:members($array),
$accum,
fn($result, $member) { $action($result, map:get($member, 'value')) }
)fold-left(
array:members($array),
$init,
fn($result, $member) { $action($result, map:get($member, 'value')) }
)If the supplied array is empty, the function returns $accuminit.
If the supplied array contains a single member $m, the function returns $accuminit => $action($m).
If the supplied array contains two members $m and $n, the function returns $accuminit => $action($m) => $action($n); and similarly for an input array with more than two members.
| Expression | Result |
|---|---|
array:fold-left(
[ true(), true(), false() ],
true(),
fn($x, $y) { $x and $y }
) | false() (Returns true if every member of the input array has an effective boolean value of |
array:fold-left(
[ true(), true(), false() ],
false(),
fn($x, $y) { $x or $y }
) | true() (Returns true if at least one member of the input array has an effective boolean value of |
array:fold-left(
[ 1, 2, 3 ],
[],
fn($x, $y) { [ $x, $y ] }
) | [[[[], 1], 2], 3] |
Evaluates the supplied function cumulatively on successive values of the supplied array.
array:fold-right( | ||
$array | as , | |
$accuminit | as , | |
$action | as | |
) as | ||
This function is deterministic, context-independent, and focus-independent.
The function is defined formally below, in terms of the equivalent fn:fold-right function for sequences.
The effect of the function is equivalent to the result of the following XPath expression.
fold-right(
array:members($array),
$accum,
fn($member, $result) { $action(map:get($member, 'value'), $result) }
)fold-right(
array:members($array),
$init,
fn($member, $result) { $action(map:get($member, 'value'), $result) }
)If the supplied array is empty, the function returns $accuminit.
If the supplied array contains a single member $m, the function returns $action($m, $accuminit).
If the supplied array contains two members $m and $n, the function returns $action($m, $action($n, $accuminit)); and similarly for an input array with more than two members.
| Expression | Result |
|---|---|
array:fold-right(
[ true(), true(), false() ],
true(),
fn($x, $y) { $x and $y }
) | false() (Returns true if every member of the input array has an effective boolean value of |
array:fold-right(
[ true(), true(), false() ],
false(),
fn($x, $y) { $x or $y }
) | true() (Returns true if at least one member of the input array has an effective boolean value of |
array:fold-right(
[ 1, 2, 3 ],
[],
fn($x, $y) { [ $x, $y ] }
) | [ 1, [ 2, [ 3, [] ] ] ] |