View Old View New View Both View Only Previous Next

This draft contains only sections that have differences from the version that it modified.

W3C

XPath and XQuery Functions and Operators 4.0

W3C Editor's Draft 23 February 2026

This version:
https://qt4cg.org/specifications/xpath-functions-40/
Latest version of XPath and XQuery Functions and Operators 4.0:
https://qt4cg.org/specifications/xpath-functions-40/
Most recent Recommendation of XPath and XQuery Functions and Operators:
https://www.w3.org/TR/2017/REC-xpath-functions-31-20170321/
Editor:
Michael Kay, Saxonica <http://www.saxonica.com/>

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.


Abstract

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.

Status of this Document

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.

Dedication

The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).


16 Higher-order functions

16.2 Basic higher-order functions

The following functions take function items as an argument.

FunctionMeaning
fn:applyMakes a dynamic call on a function with an argument list supplied in the form of an array.
fn:chainApplies a sequence of functions starting with an initial input.
fn:do-untilProcesses a supplied value repeatedly, continuing when some condition is false, and returning the value that satisfies the condition.
fn:everyReturns true if every item in the input sequence matches a supplied predicate.
fn:filterReturns those items from the sequence $input for which the supplied function $predicate returns true.
fn:fold-leftProcesses 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-rightProcesses 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-eachApplies 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-pairApplies 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:highestReturns 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-whereReturns the positions in an input sequence of items that match a supplied predicate.
fn:lowestReturns 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-applyPerforms partial application of a function item by binding values to selected arguments.
fn:partitionPartitions 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-leftProduces the complete (ordered) sequence of allsuccessive partial results from every new value the accumulator is assigned to during thethe evaluation of fn:fold-leftfn:fold-left with the same arguments.
fn:scan-rightProduces the complete (ordered) sequence of allsuccessive partial results from every new value the accumulator is assigned to during thethe evaluation of fn:fold-rightfn:fold-right with the same arguments.
fn:someReturns true if at least one item in the input sequence matches a supplied predicate.
fn:sortSorts a supplied sequence, based on the value of a number of sort keys supplied as functions.
fn:sort-withSorts a supplied sequence, according to the order induced by the supplied comparator functions.
fn:subsequence-whereReturns a contiguous sequence of items from $input, with the start and end points located by applying predicates.
fn:take-whileReturns items from the input sequence prior to the first one that fails to match a supplied predicate.
fn:transitive-closureReturns all the nodes reachable from a given start node by applying a supplied function repeatedly.
fn:while-doProcesses 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.

16.2.15 fn:scan-left

Changes in 4.0  

  1. New in 4.0  [Issue 982 PR 1296 23 June 2024]

Summary

Produces the complete (ordered) sequence of allsuccessive partial results from every new value the accumulator is assigned to during thethe evaluation of fn:fold-leftfn:fold-left with the same arguments.

Signature
fn:scan-left(
$inputas item()*,
$zeroaccumas item()*,
$actionas fn(item()*, item()) as item()*
) as array(*)*
Properties

This function is deterministic, context-independent, and focus-independent.

Rules

The function is equivalent to the following implementation in XPath (return clause added in comments for completeness):

let $scan-left-inner := fn(
  $input  as item()*, 
  $zero   as item()*, 
  $action as fn(item()*, item()) as item()*,
  $self   as fn(*)
) as array(*)* {
  let $result := [$zero]
  return if (empty($input)) then (
    $result
  ) else (
    $result, $self(tail($input), $action($zero, head($input)), $action, $self)
  )
}
let $scan-left := fn(
  $input  as item()*, 
  $zero   as item()*, 
  $action as fn(item()*, item()) as item()*
) as array(*)*  {
  $scan-left-inner($input, $zero, $action, $scan-left-inner)
}
(: return $scan-left(1 to 10, 0, op('+'))  :)
Error Conditions

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 $zero or the result of a previous application of $action, and the second is any single item from the sequence $input.

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), $accum, $action ).

Formal Equivalent

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 )]
Notes
  1. Note that each intermediate result is placed in a separate single-member arrayDM. This is necessary because we cannot represent a sequence of results, some or all of which are a sequence - that is "sequence of sequences" as just a single sequence.

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.

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

Produce the intermediate results of mapping each number in a sequence to its doubled value. This example shows the necessity to place each intermediate result (sequence) into a single-member arrayDM - otherwise the sequence of sequences (intermediate results) would not be possible to express as a single sequence without losing completely the intermediate results.

Expression:
let $double := fn($x) { 2 * $x }
return scan-left(1 to 3, (), fn($seq, $it) { $seq , $double($it) })
scan-left(1 to 5, 1, op('*'))
Result:
[ () ], [ 2 ], [ (2, 4) ], [ (2, 4, 6) ] ]
[ 1 ], [ 1 ], [ 2 ], [ 6 ], [ 24 ], [ 120 ]

Produce the factorials of all numbers from 0 to 5

Expression:
scan-left(1 to 5, 1, op('*'))
scan-left(1 to 3, (), fn($a, $b) { $b, $a })
Result:
[ 1 ], [ 1 ], [ 2 ], [ 6 ], [ 24 ], [ 120 ]
[ () ], [ 1 ], [ (2, 1) ], [ (3, 2, 1) ] ]

16.2.16 fn:scan-right

Changes in 4.0  

  1. New in 4.0

Summary

Produces the complete (ordered) sequence of allsuccessive partial results from every new value the accumulator is assigned to during thethe evaluation of fn:fold-rightfn:fold-right with the same arguments.

Signature
fn:scan-right(
$inputas item()*,
$zeroaccumas item()*,
$actionas fn(item()*, item()) as item()*
) as array(*)*
Properties

This function is deterministic, context-independent, and focus-independent.

Rules

The function is equivalent to the following implementation in XPath (return clause in comments added for completeness):

let $scan-right-inner := fn(
  $input  as item()*,
  $zero   as item()*,
  $action as fn(item()*, item()) as item()*, $self as fn(*)
) as array(*)* {
  if (empty($input)) then (
    [ $zero ]
  ) else (
    let $rightResult := $self(tail($input), $zero, $action, $self)
    return ([ $action(head($input), head($rightResult)) ], $rightResult)
  )
}
let $scan-right := function(
  $input as item()*,
  $zero  as item()*,
  $f     as fn(item()*, item()) as item()*
) as array(*)* {
  $scan-right-inner($input, $zero, $f, $scan-right-inner)
}        
(: return $scan-right(1 to 10, 0, op('+')) :)
Error Conditions

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 $zero or the result of a previous application of $action.

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), $accum, $action ).

Formal Equivalent

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 )]
Notes
  1. Note that each intermediate result is placed in a separate single-member arrayDM. This is necessary because we cannot represent a sequence of results, some or all of which are a sequence - that is "sequence of sequences" as just a single sequence.

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.

Examples
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], [()]