16 Higher-order functions

16.1 Functions on functions

The functions included in this section operate on function items, that is, values referring to a function.

[Definition] Functions that accept functions among their arguments, or that return functions in their result, are described in this specification as higher-order functions. Some host languages may exclude higher-order functions from the set of functions that they support, or may include such functions in an optional conformance feature.

Note:

Some functions such as fn:parse-json allow the option of supplying a callback function for example to define exception behavior. Where this is not essential to the use of the function, the function has not been classified as higher-order for this purpose; in applications where function items cannot be created, these particular options will not be available.

Function Meaning
fn:function-lookup Returns the function having a given name and arity, if there is one.
fn:function-name Returns the name of the function identified by a function item.
fn:function-arity Returns the arity of the function identified by a function item.

16.1.1 fn:function-lookup

Summary

Returns the function having a given name and arity, if there is one.

Signature
fn:function-lookup(
$name as xs:QName,
$arity as xs:integer
) as function(*)?
Properties

This function is ·deterministic·, ·context-dependent·, ·focus-dependent·, and ·higher-order·.

Rules

A call to fn:function-lookup returns the function obtained by looking up the expanded QName supplied as $name and the arity supplied as $arity in the named functions component of the dynamic context (specifically, the dynamic context of the call to fn:function-lookup).

Furthermore, if that function has an implementation-dependent implementation (see note below), then the implementation of the function returned by fn:function-lookup is associated with the static and dynamic context of the call to fn:function-lookup.

Note:

The above rule deliberately uses the same wording as the corresponding rule for Named Function References. The term "a function [with] an implementation-dependent implementation" essentially means a function whose implementation is provided by the language processor rather than by the stylesheet or query author. This rule is therefore relevant to built-in functions and vendor-supplied extension functions whose result depends on the context of the function call.

Otherwise (if no known function can be identified by name and arity), an empty sequence is returned.

If the arguments to fn:function-lookup identify a function that is present in the static context of the function call, the function will always return the same function that a static reference to this function would bind to. If there is no such function in the static context, then the results depend on what is present in the dynamic context, which is ·implementation-defined·.

Notes

This function can be useful where there is a need to make a dynamic decision on which of several statically known functions to call. It can thus be used as a substitute for polymorphism, in the case where the application has been designed so several functions implement the same interface.

The function can also be useful in cases where a query or stylesheet module is written to work with alternative versions of a library module. In such cases the author of the main module might wish to test whether an imported library module contains or does not contain a particular function, and to call a function in that module only if it is available in the version that was imported. A static call would cause a static error if the function is not available, whereas getting the function using fn:function-lookup allows the caller to take fallback action in this situation.

If the function that is retrieved by fn:function-lookup is ·context-dependent·, that is, if it has dependencies on the static or dynamic context of its caller, the context that applies is the static and/or dynamic context of the call to the fn:function-lookup function itself. The context thus effectively forms part of the closure of the returned function. In practice this applies only where the target of fn:function-lookup is a built-in function, because user-defined functions never depend on the static or dynamic context of the function call. The rule applies recursively, since fn:function-lookup is itself a context-dependent built-in function.

These specifications do not define any circumstances in which the dynamic context will contain functions that are not present in the static context, but neither do they rule this out. For example an API may provide the ability to add functions to the dynamic context. Equally, these specifications do not define any mechanism for creating context-dependent functions other than the built-in context-dependent functions, but neither do they rule out the existence of such functions.

The mere fact that a function exists and has a name does not of itself mean that the function is present in the dynamic context. For example, functions obtained through use of the fn:load-xquery-module function are not added to the dynamic context.

Examples

The expression fn:function-lookup(xs:QName('fn:substring'), 2)('abcd', 2) returns 'bcd'.

The expression (fn:function-lookup(xs:QName('xs:dateTimeStamp'), 1), xs:dateTime#1)[1] ('2011-11-11T11:11:11Z') returns an xs:dateTime value set to the specified date, time, and timezone; if the implementation supports XSD 1.1 then the result will be an instance of the derived type xs:dateTimeStamp. The query is written to ensure that no failure occurs when the implementation does not recognize the type xs:dateTimeStamp.

The expression let $f := fn:function-lookup(xs:QName('zip:binary-entry'), 2) return if (exists($f)) then $f($href, $entry) else () returns the result of calling zip:binary-entry($href, $entry) if the function is available, or an empty sequence otherwise.

16.1.2 fn:function-name

Summary

Returns the name of the function identified by a function item.

Signature
fn:function-name(
$function as function(*)
) as xs:QName?
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

If $function refers to a named function, fn:function-name($func) returns the name of that function.

Otherwise ($function refers to an anonymous function), fn:function-name($function) returns an empty sequence.

The prefix part of the returned QName is ·implementation-dependent·.

Examples

The expression fn:function-name(fn:substring#2) returns fn:QName("http://www.w3.org/2005/xpath-functions", "fn:substring"). (The namespace prefix of the returned QName is not predictable.)

The expression fn:function-name(function($node){count($node/*)}) returns ().

16.1.3 fn:function-arity

Summary

Returns the arity of the function identified by a function item.

Signature
fn:function-arity(
$function as function(*)
) as xs:integer
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

The fn:function-arity function returns the arity (number of arguments) of the function identified by $function.

Examples

The expression fn:function-arity(fn:substring#2) returns 2.

The expression fn:function-arity(function($node){name($node)}) returns 1.

The expression let $initial := fn:substring(?, 1, 1) return fn:function-arity($initial) returns 1.

16.2 Basic higher-order functions

The following functions take function items as an argument.

Function Meaning
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:filter Returns those items from the sequence $input for which the supplied function $predicate returns true.
fn:all Returns true if all items in the input sequence match a supplied predicate.
fn:some Returns true if at least one item in the input sequence matches a supplied predicate.
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:iterate-while Processes a supplied value repeatedly, continuing while some condition remains true, and returning the first value that does not satisfy the condition.
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:index-where Returns the position in an input sequence of items that match a supplied predicate.
fn:items-after Returns the items from the input sequence that follow the first item to match a supplied predicate.
fn:items-before Returns the items from the input sequence that precede the first item to match a supplied predicate.
fn:items-starting-where Returns the items from the input sequence starting from the first item to match a supplied predicate.
fn:items-ending-where Returns the items from the input sequence ending with the first item to match a supplied predicate.
fn:sort Sorts a supplied sequence, based on the value of a sort key supplied as a function.
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: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:apply Makes a dynamic call on a function with an argument list supplied in the form of an array.

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.1 fn:for-each

Summary

Applies the function item $action to every item from the sequence $input in turn, returning the concatenation of the resulting sequences in order.

Signature
fn:for-each(
$input as item()*,
$action as function(item()) as item()*
) as item()*
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

The effect of the function is equivalent to the following implementation in XQuery:

declare function fn:for-each($input, $action) {
  if (fn:empty($input))
  then ()
  else ($action(fn:head($input)), fn:for-each(fn:tail($input), $action))
};

or its equivalent in XSLT:

<xsl:function name="fn:for-each">
  <xsl:param name="iinput"/>
  <xsl:param name="action"/>
  <xsl:if test="fn:exists($input)">
    <xsl:sequence select="$action(fn:head($input)), fn:for-each(fn:tail($input), $action)"/>
  </xsl:if>
</xsl:function>
         
Notes

The function call fn:for-each($SEQ, $F) is equivalent to the expression for $i in $SEQ return $F($i), assuming that ordering mode is ordered.

Examples

The expression fn:for-each(1 to 5, function($a) { $a * $a }) returns (1, 4, 9, 16, 25).

The expression fn:for-each(("john", "jane"), fn:string-to-codepoints#1) returns (106, 111, 104, 110, 106, 97, 110, 101).

The expression fn:for-each(("23", "29"), xs:int#1) returns (23, 29).

16.2.2 fn:filter

Summary

Returns those items from the sequence $input for which the supplied function $predicate returns true.

Signature
fn:filter(
$input as item()*,
$predicate as function(item()) as xs:boolean
) as item()*
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

The effect of the function is equivalent to the following implementation in XQuery:

declare function fn:filter(
        $input as item()*,
        $predicate as function(item()) as xs:boolean)
        as item()* {
  if (fn:empty($input))
  then ()
  else ( fn:head($input)[$predicate(.) eq fn:true()], 
         fn:filter(fn:tail($input), $predicate)
       )
};

or its equivalent in XSLT:

<xsl:function name="fn:filter" as="item()*">
  <xsl:param name="input" as="item()*"/>
  <xsl:param name="predicate" as="function(item()) as xs:boolean"/>
  <xsl:if test="fn:exists($input)">
    <xsl:sequence select="fn:head($input)[$f(.) eq fn:true()], fn:filter(fn:tail($input), $f)"/>
  </xsl:if>
</xsl:function>
         
Error Conditions

As a consequence of the function signature and the function calling rules, a type error occurs if the supplied function $predicate returns anything other than a single xs:boolean item; there is no conversion to an effective boolean value.

Notes

The function call fn:filter($SEQ, $F) has a very similar effect to the expression $SEQ[$F(.)]. There are some differences, however. In the case of fn:filter, the function $F is required to return a boolean; there is no special treatment for numeric predicate values, and no conversion to an effective boolean value. Also, with a filter expression $SEQ[$F(.)], the focus within the predicate is different from that outside; this means that the use of a context-sensitive function such as fn:lang#1 will give different results in the two cases.

Examples

The expression fn:filter(1 to 10, function($a) {$a mod 2 = 0}) returns (2, 4, 6, 8, 10).

The expression fn:filter((), fn:lang("en", ?)) returns ().

16.2.3 fn:all

Summary

Returns true if all items in the input sequence match a supplied predicate.

Signature
fn:all(
$input as item()*,
$predicate as function(item()) as xs:boolean := fn:identity#1
) as xs:boolean
Properties

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

Rules

The effect of the function is equivalent to the following implementation in XQuery:

declare function fn:all(
        $input as item()*,
        $predicate as function(item()) as xs:boolean) 
        as xs:boolean {
  every $i in $input satisfies $predicate($i)
};

or its equivalent in XSLT:

<xsl:function name="fn:all" as="xs:boolean">
  <xsl:param name="input" as="item()*"/>
  <xsl:param name="predicate" as="function(item()) as xs:boolean"/>
  <xsl:sequence select="every $i in $input satisfies $predicate($i)"/>
</xsl:function>
         
Notes

If the second argument is omitted, the first argument must be a sequence of xs:boolean values.

The implementation may deliver a result as soon as one item is found for which the predicate returns false; it is not required to evaluate the predicate for every item.

Examples

The expression fn:all(()) returns true().

The expression fn:all((1=1, 2=2, 3=4)) returns false().

The expression fn:all((), fn:boolean#1) returns true().

The expression fn:all((1, 3, 7), ->{. mod 2 = 1}) returns true().

The expression fn:all(-5 to +5, ->{. ge 0})) returns false().

The expression fn:all(("January", "February", "March", "April", "September", "October", "November", "December"), contains(?, "r")) returns true().

The expression fn:all(("January", "February", "March", "April", "September", "October", "November", "December")!contains(., "r")) returns true().

History

New in 4.0. Accepted 2022-09-13.

16.2.4 fn:some

Summary

Returns true if at least one item in the input sequence matches a supplied predicate.

Signature
fn:some(
$input as item()*,
$predicate as function(item()) as xs:boolean := fn:identity#1
) as xs:boolean
Properties

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

Rules

The effect of the function is equivalent to the following implementation in XQuery:

declare function fn:some(
        $input as item()*,
        $predicate as function(item()) as xs:boolean) 
        as xs:boolean {
  some $i in $input satisfies $predicate($i)
};

or its equivalent in XSLT:

<xsl:function name="fn:some" as="xs:boolean">
  <xsl:param name="input" as="item()*"/>
  <xsl:param name="predicate" as="function(item()) as xs:boolean"/>
  <xsl:sequence select="some $i in $input satisfies $predicate($i)"/>
</xsl:function>
         
Notes

If the second argument is omitted, the first argument must be a sequence of xs:boolean values.

The implementation may deliver a result as soon as one item is found for which the predicate returns true; it is not required to evaluate the predicate for every item.

Examples

The expression fn:some(()) returns false().

The expression fn:some((1=1, 2=2, 3=4)) returns true().

The expression fn:some((), fn:boolean#1) returns false().

The expression fn:some((1, 3, 7), ->{. mod 2 = 1}) returns true().

The expression fn:some(-5 to +5, ->{. ge 0})) returns true().

The expression fn:some(("January", "February", "March", "April", "September", "October", "November", "December"), contains(?, "z")) returns false().

The expression fn:some(("January", "February", "March", "April", "September", "October", "November", "December")!contains(., "r")) returns true().

History

New in 4.0. Accepted 2022-09-13.

16.2.5 fn:fold-left

Summary

Processes the supplied sequence from left to right, applying the supplied function repeatedly to each item in turn, together with an accumulated result value.

Signature
fn:fold-left(
$input as item()*,
$zero as item()*,
$action as function(item()*, item()) as item()*
) as item()*
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

The effect of the function is equivalent to the following implementation in XQuery:

declare function fn:fold-left(
        $input as item()*,
        $zero as item()*,
        $action as function(item()*, item()) as item()*) 
        as item()* {
  if (fn:empty($input))
  then $zero
  else fn:fold-left(fn:tail($input), $action($zero, fn:head($input)), $action)
};

or its equivalent in XSLT:

<xsl:function name="fn:fold-left" as="item()*">
  <xsl:param name="input" as="item()*"/>
  <xsl:param name="zero" as="item()*"/>
  <xsl:param name="action" as="function(item()*, item()) as item()*"/>
  <xsl:choose>
    <xsl:when test="fn:empty($input)">
      <xsl:sequence select="$zero"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="fn:fold-left(fn:tail($input), $action($zero, fn:head($input)), $action)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>
         
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.

Notes

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

Examples

The expression fn:fold-left(1 to 5, 0, function($a, $b) { $a + $b }) returns 15. (This returns the sum of the items in the sequence).

The expression fn:fold-left((2,3,5,7), 1, function($a, $b) { $a * $b }) returns 210. (This returns the product of the items in the sequence).

The expression fn:fold-left((true(), false(), false()), false(), function($a, $b) { $a or $b }) returns true(). (This returns true if any item in the sequence has an effective boolean value of true).

The expression fn:fold-left((true(), false(), false()), false(), function($a, $b) { $a and $b }) returns false(). (This returns true only if every item in the sequence has an effective boolean value of true).

The expression fn:fold-left(1 to 5, (), function($a, $b) {($b, $a)}) returns (5,4,3,2,1). (This reverses the order of the items in a sequence).

The expression fn:fold-left(1 to 5, "", fn:concat(?, ".", ?)) returns ".1.2.3.4.5".

The expression fn:fold-left(1 to 5, "$zero", fn:concat("$f(", ?, ", ", ?, ")")) returns "$f($f($f($f($f($zero, 1), 2), 3), 4), 5)".

The expression fn:fold-left(1 to 5, map{}, function($map, $n) {map:put($map, $n, $n*2)}) returns map{1:2, 2:4, 3:6, 4:8, 5:10}.

16.2.6 fn:fold-right

Summary

Processes the supplied sequence from right to left, applying the supplied function repeatedly to each item in turn, together with an accumulated result value.

Signature
fn:fold-right(
$input as item()*,
$zero as item()*,
$action as function(item(), item()*) as item()*
) as item()*
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

The effect of the function is equivalent to the following implementation in XQuery:

declare function fn:fold-right(
        $input as item()*, 
        $zero as item()*, 
        $action as function(item(), item()*) as item()*) 
        as item()* {
  if (fn:empty($input))
  then $zero
  else $action(fn:head($input), fn:fold-right(fn:tail($input), $zero, $action))
};

or its equivalent in XSLT:

<xsl:function name="fn:fold-right" as="item()*">
  <xsl:param name="input" as="item()*"/>
  <xsl:param name="zero" as="item()*"/>
  <xsl:param name="action" as="function(item(), item()*) as item()*"/>
  <xsl:choose>
    <xsl:when test="fn:empty($input)">
      <xsl:sequence select="$zero"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:sequence select="$action(fn:head($input), fn:fold-right(fn:tail($input), $zero, $action))"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:function>
         
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.

Notes

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

Examples

The expression fn:fold-right(1 to 5, 0, function($a, $b) { $a + $b }) returns 15. (This returns the sum of the items in the sequence).

The expression fn:fold-right(1 to 5, "", fn:concat(?, ".", ?)) returns "1.2.3.4.5.".

The expression fn:fold-right(1 to 5, "$zero", concat("$f(", ?, ", ", ?, ")")) returns "$f(1, $f(2, $f(3, $f(4, $f(5, $zero)))))".

16.2.7 fn:iterate-while

Summary

Processes a supplied value repeatedly, continuing while some condition remains true, and returning the first value that does not satisfy the condition.

Signature
fn:iterate-while(
$input as item()*,
$predicate as function(item()*) as xs:boolean,
$action as function(item()*) as item()*
) as item()*
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

Informally, the function behaves as follows:

  1. The supplied $input value is tested against the supplied $predicate.

  2. If the result of the predicate is true, $action($input) is evaluated, the resulting value is used as a new $input, and the process repeats from step 1.

  3. If the result of the predicate is false, the function returns the value of $input.

More formally, the function is equivalent to the following implementation in XQuery:

declare function fn:iterate-while(
  $input     as item()*,
  $predicate as function(item()*) as xs:boolean,
  $action    as function(item()*) as item()*
) as item()* {
  if ($predicate($input)) then (
    fn:iterate-while($action($input), $predicate, $action)
  ) else (
    $input
  )
};
Notes

While-loops are very common in procedural programming languages, and this function provides a way to write functionally clean and interruptible iterations without side-effects. An initial value is tested and replaced by new values until it matches a given condition. Depending on the use case, the value can be a simple atomic item or an arbitrarily complex data structure.

Note that, just as when writing recursive functions, it is easy to construct infinite loops.

Examples

The expression fn:iterate-while(2, -> { . < 100 }, -> { . * . }) returns 256.

The expression let $input := (0 to 4, 6 to 10) return fn:iterate-while(0, function($n) { $n = $input }, function($n) { $n + 1 }) returns 5. (This returns the first positive number missing in a sequence.)

The expression fn:iterate-while( 1 to 9, function($seq) { head($seq) < 5 }, function($seq) { tail($seq) } ) returns (5, 6, 7, 8, 9).

The expression let $input := 3936256 return fn:iterate-while( $input, function($result) { abs($result * $result - $input) >= 0.0000000001 }, function($guess) { ($guess + $input div $guess) div 2 } ) returns 1984. (This computes the square root of a number.)

The following example generates random doubles. It is interrupted once a number exceeds a given limit:

let $r := random-number-generator()
let $map := fn:iterate-while(
  $r,
  function($r) {
    $r?number < 0.8
  },
  function($r) {
    map:put($r?next(), 'numbers', ($r?numbers, $r?number))
  }
)
return $map?numbers
            

16.2.8 fn:for-each-pair

Summary

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.

Signature
fn:for-each-pair(
$input1 as item()*,
$input2 as item()*,
$action as function(item(), item()) as item()*
) as item()*
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

The effect of the function is equivalent to the following implementation in XQuery:

declare function fn:for-each-pair($input1, $input2, $action)
{
   if(fn:exists($input1) and fn:exists($input2)) 
   then (
     $action(fn:head($input1), fn:head($input2)),
     fn:for-each-pair(fn:tail($input1), fn:tail($input2), $action)
   )
   else ()
};

or its equivalent in XSLT:

<xsl:function name="fn:for-each-pair">
  <xsl:param name="input1"/>
  <xsl:param name="input2"/>
  <xsl:param name="action"/>
  <xsl:if test="fn:exists($input1) and fn:exists($input2)">
    <xsl:sequence select="$action(fn:head($input1), fn:head($input2))"/>
    <xsl:sequence select="fn:for-each-pair(fn:tail($input1), fn:tail($input2), $action)"/>
  </xsl:if>
</xsl:function>
         
Notes

If one sequence is longer than the other, excess items in the longer sequence are ignored.

Examples

The expression fn:for-each-pair(("a", "b", "c"), ("x", "y", "z"), concat#2) returns ("ax", "by", "cz").

The expression fn:for-each-pair(1 to 5, 1 to 5, function($a, $b){10*$a + $b}) returns (11, 22, 33, 44, 55).

The expression let $s := 1 to 8 return fn:for-each-pair($s, tail($s), function($a, $b){$a*$b}) returns (2, 6, 12, 20, 30, 42, 56).

16.2.9 fn:index-where

Summary

Returns the position in an input sequence of items that match a supplied predicate.

Signature
fn:index-where(
$input as item()*,
$predicate as function(item()) as xs:boolean
) as xs:integer*
Properties

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

Rules

The result of the function is a sequence of integers, in monotonic ascending order, representing the 1-based positions in the input sequence of those items for which the supplied predicate function returns true.

More formally, the function returns the result of the expression:

fn:index-of($input!$predicate(.), true())
Examples

The expression fn:index-where((), fn:boolean#1) returns ().

The expression fn:index-where((0, 4, 9), fn:boolean#1) returns (2, 3).

The expression fn:index-where(1 to 10, ->{. mod 2 = 0})) returns (2, 4, 6, 8, 10).

The expression fn:index-where(("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"), fn:contains(?, "r")) returns (1, 2, 3, 4, 9, 10, 11, 12).

History

New in 4.0. Accepted 2022-09-20.

16.2.10 fn:items-after

Summary

Returns the items from the input sequence that follow the first item to match a supplied predicate.

Signature
fn:items-after(
$input as item()*,
$predicate as function(item()) as xs:boolean
) as item()*
Properties

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

Rules

The supplied $predicate function is called for each item in the input sequence $input, to return a boolean value. Let $P be the 1-based position of the first item to match the predicate, or -1 if no item matches the predicate.

The function then returns if ($P lt 0) then () else fn:subsequence($input, $P + 1).

Examples

The expression fn:items-after(10 to 20, ->{. gt 12}) returns (14, 15, 16, 17, 18, 19, 20).

The expression fn:items-after(("January", "February", "March", "April", "May"), fn:starts-with(?, "A")) returns ("May").

The expression fn:items-after(10 to 20, ->{. gt 100}) returns ().

The expression fn:items-after((), fn:boolean#1) returns ().

The expression parse-xml("<doc><p/><p/><h2/><img/></doc>")//doc/* => fn:items-after(->{fn:boolean(self::h2)}) returns <img/>.

History

New in 4.0. Accepted 2022-10-25.

16.2.11 fn:items-before

Summary

Returns the items from the input sequence that precede the first item to match a supplied predicate.

Signature
fn:items-before(
$input as item()*,
$predicate as function(item()) as xs:boolean
) as item()*
Properties

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

Rules

The supplied $predicate function is called for each item in the input sequence $input, to return a boolean value. Let $P be the 1-based position of the first item to match the predicate, or -1 if no item matches the predicate.

The function then returns if ($P lt 0) then $seq else fn:subsequence($input, 1, $P - 1).

Examples

The expression fn:items-before(10 to 20, ->{. gt 12}) returns (10, 11, 12).

The expression fn:items-before(("January", "February", "March", "April", "May"), fn:starts-with(?, "A")) returns ("January", "February", "March").

The expression fn:items-before(10 to 20, ->{. gt 100}) returns (10 to 20).

The expression fn:items-before((), fn:boolean#1) returns ().

The expression parse-xml("<doc><p/><p/><h2/><img/></doc>")//doc/* => fn:items-before(->{fn:boolean(self::h2)}) returns <p/>,<p/>.

The expression ("Aardvark", "Antelope", "Bison", "Buffalo", "Camel", "Dingo") => fn:items-starting-where(->{fn:starts-with("B")}) => fn:items-before(->{fn:starts-with("D")}) returns "Bison", "Buffalo", "Camel".

History

New in 4.0. Accepted 2022-10-25.

16.2.12 fn:items-starting-where

Summary

Returns the items from the input sequence starting from the first item to match a supplied predicate.

Signature
fn:items-starting-where(
$input as item()*,
$predicate as function(item()) as xs:boolean
) as item()*
Properties

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

Rules

The supplied $predicate function is called for each item in the input sequence $input, to return a boolean value. Let $P be the 1-based position of the first item to match the predicate, or -1 if no item matches the predicate.

The function then returns if ($P lt 0) then () else fn:subsequence($input, $P).

Examples

The expression fn:items-starting-where(10 to 20, ->{. gt 12}) returns (13, 14, 15, 16, 17, 18, 19, 20).

The expression fn:items-starting-where(("January", "February", "March", "April", "May"), fn:starts-with(?, "A")) returns ("April", "May").

The expression fn:items-starting-where(10 to 20, ->{. gt 100}) returns ().

The expression fn:items-starting-where((), fn:boolean#1) returns ().

The expression parse-xml("<doc><p/><p/><h2/><img/></doc>")//doc/* => fn:items-starting-where(->{fn:boolean(self::h2)}) returns (<h2/>,<img/>).

History

New in 4.0. Accepted 2022-10-25.

16.2.13 fn:items-ending-where

Summary

Returns the items from the input sequence ending with the first item to match a supplied predicate.

Signature
fn:items-until(
$input as item()*,
$predicate as function(item()) as xs:boolean
) as item()*
Properties

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

Rules

The supplied $predicate function is called for each item in the input sequence $input, to return a boolean value. Let $P be the 1-based position of the first item to match the predicate, or -1 if no item matches the predicate.

The function then returns if ($P lt 0) then $seq else fn:subsequence($input, 1, $P).

Examples

The expression fn:items-ending-where(10 to 20, ->{. gt 12}) returns (10, 11, 12, 13).

The expression fn:items-ending-where(("January", "February", "March", "April", "May"), fn:starts-with(?, "A")) returns ("January", "February", "March", "April").

The expression fn:items-ending-where(10 to 20, ->{. gt 100}) returns (10 to 20).

The expression fn:items-ending-where((), fn:boolean#1) returns ().

The expression parse-xml("<doc><p/><p/><h2/><img/></doc>")//doc/* => fn:items-ending-where(->{fn:boolean(self::h2)}) returns <p/>,<p/>,<h2/>.

History

New in 4.0. Accepted 2022-10-25.

16.2.14 fn:sort

Summary

Sorts a supplied sequence, based on the value of a sort key supplied as a function.

Signatures
fn:sort(
$input as item()*
) as item()*
fn:sort(
$input as item()*,
$collation as xs:string?
) as item()*
fn:sort(
$input as item()*,
$collation as xs:string?,
$key as function(item()) as xs:anyAtomicType*
) as item()*
Properties

The one-argument form of this function is ·deterministic·, ·context-dependent·, and ·focus-independent·. It depends on collations.

The two-argument form of this function is ·deterministic·, ·context-dependent·, and ·focus-independent·. It depends on collations.

The three-argument form of this function is ·deterministic·, ·context-dependent·, ·focus-independent·, and ·higher-order·. It depends on collations.

Rules

Calling the single-argument version of the function is equivalent to calling the two-argument form with default-collation() as the second argument: that is, it sorts a sequence of items according to the typed value of the items, using the default collation to compare strings.

Calling the two-argument version of the function is equivalent to calling the three-argument form with fn:data#1 as the third argument: that is, it sorts a sequence of items according to the typed value of the items, using a specified collation to compare strings.

In the case of both fn:sort#2 and fn:sort#3, supplying an empty sequence as the second argument is equivalent to supplying fn:default-collation(). For more information on collations see 5.3.5 Choosing a collation.

The result of the function is obtained as follows:

  • For each item in the sequence $input, the function supplied as $key is evaluated with that item as its argument. The resulting values are the sort keys of the items in the input sequence.

  • The result sequence contains the same items as the input sequence $input, but generally in a different order.

  • Let $C be the selected collation, or the default collation where applicable.

  • The order of items in the result is such that, given two items $A and $B:

    1. Let $REL be the result of evaluating op:lexicographic-compare($key($A), $key($B), $C) where op:lexicographic-compare($a, $b, $C) is defined as follows:

      
      if (empty($a) and empty($b)) then 0 
      else if (empty($a)) then -1
      else if (empty($b)) then +1
      else let $rel = op:simple-compare(head($a), head($b), $C)
           return if ($rel eq 0)
                  then op:lexicographic-compare(tail($a), tail($b), $C)
                  else $rel
                              
    2. Here op:simple-compare($k1, $k2) is defined as follows:

      
      if ($k1 instance of union(xs:string, xs:anyURI, xs:untypedAtomic)
              and $k2 instance of union(xs:string, xs:anyURI, xs:untypedAtomic))
          then fn:compare($k1, $k2, $C)
          else if ($k1 eq $k2 or (fn:is-NaN($k1) and fn:is-NaN($k2))) then 0
          else if (fn:is-NaN($k1) or $k2 lt $k2) then -1
          else +1          
                           

      Note:

      This raises an error if two keys are not comparable, for example if one is a string and the other is a number, or if both belong to a non-ordered type such as xs:QName.

  • If $REL eq 0, then the relative order of $A and $B in the output is the same as their relative order in the input (that is, the sort is stable)

  • Otherwise, if $REL lt 0, then $A precedes $B in the output.

Error Conditions

If the set of computed sort keys contains values that are not comparable using the lt operator then the sort operation will fail with a type error ([err:XPTY0004]XP).

Notes

XSLT and XQuery both provide native sorting capability, but previous releases of XPath provided no sorting functionality for use in standalone environments.

In addition there are cases where this function may be more flexible than the built-in sorting capability for XQuery or XSLT, for example when the sort key or collation is chosen dynamically, or when the sort key is a sequence of items rather than a single item.

The results are compatible with the results of XSLT sorting (using xsl:sort) in the case where the sort key evaluates to a sequence of length zero or one, given the options stable="yes" and order="ascending".

The results are compatible with the results of XQuery sorting (using the order by clause) in the case where the sort key evaluates to a sequence of length zero or one, given the options stable, ascending, and empty least.

Examples

The expression fn:sort((1, 4, 6, 5, 3)) returns (1, 3, 4, 5, 6).

The expression fn:sort((1, -2, 5, 10, -10, 10, 8), (), fn:abs#1) returns (1, -2, 5, 8, 10, -10, 10).

To sort a set of strings $in using Swedish collation:

let $SWEDISH := "http://www.w3.org/2013/collation/UCA?lang=se"
return fn:sort($in, $SWEDISH)
            

To sort a sequence of employees by last name as the major sort key and first name as the minor sort key, using the default collation:

fn:sort($employees, (), function($emp) {$emp/name ! (last, first)})

16.2.15 fn:highest

Summary

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.

Signatures
fn:highest(
$input as item()*
) as item()*
fn:highest(
$input as item()*,
$collation as xs:string?
) as item()*
fn:highest(
$input as item()*,
$collation as xs:string?,
$key as function(item()) as xs:anyAtomicType*
) as item()*
Properties

This function is ·deterministic·, ·context-dependent·, and ·focus-independent·. It depends on collations.

Rules

The second argument, $collation, defaults to ().

Supplying an empty sequence as $collation is equivalent to supplying fn:default-collation(). For more information on collations see 5.3.5 Choosing a collation.

The third argument defaults to the function data#1.

Let $modified-key be the function:


function($item){
   $key($item) => fn:data() ! (
      if (. instance of xs:untypedAtomic)
      then xs:double(.)
      else .)
}

That is, the supplied function for computing key values is wrapped in a function that converts any xs:untypedAtomic values in its result to xs:double. This makes the function consistent with the behavior of fn:min and fn:max, but inconsistent with fn:sort, which treats untyped values as strings.

The result of the function is obtained as follows:

  • If the input is an empty sequence, the result is an empty sequence.

  • The input sequence is sorted, by applying the function fn:sort($input, $collation, $modified-key).

  • Let $C be the selected collation, or the default collation where applicable.

  • Let $B be the last item in the sorted sequence.

  • The function returns those items $A from the input sequence such that (fn:deep-equal($key($A), $key($B), $C), retaining their order.

Error Conditions

If the set of computed keys contains xs:untypedAtomic values that are not castable to xs:double then operation will fail with a dynamic error ([err:FORG0001]FO).

If the set of computed keys contains values that are not comparable using the lt operator then the sort operation will fail with a type error ([err:XPTY0004]XP).

Examples
let $e := <a x="10" y="5" z="2"/>

The expression fn:highest($e/@*) ! name() returns ("y"). (The attribute values are compared as strings.)

The expression fn:highest($e/@*, (), fn:number#1) ! name() returns ("x"). (Here the attribute values are compared as numbers.)

The expression fn:highest(("red", "green", "blue"), (), fn:string-length#1) returns ("green").

The expression fn:highest(("red", "green", "blue"), (), map{"red": xs:hexBinary('FF0000'), "green": xs:hexBinary('008000'), "blue": xs:hexBinary('0000FF')}) returns ("red").

The expression fn:highest(("red", "orange", "yellow", "green", "blue", "indigo", "violet"), (), fn:string-length#1) returns ("orange", "yellow", "indigo", "violet").

The expression fn:highest(1 to 25, (), ->{. idiv 10}) returns (20, 21, 22, 23, 24, 25).

To find employees having the highest salary:

fn:highest($employees, (), ->{xs:decimal(salary)})
History

New in 4.0. Accepted 2022-09-20.

16.2.16 fn:lowest

Summary

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.

Signatures
fn:lowest(
$input as item()*
) as item()*
fn:lowest(
$input as item()*,
$collation as xs:string?
) as item()*
fn:lowest(
$input as item()*,
$collation as xs:string?,
$key as function(item()) as xs:anyAtomicType*
) as item()*
Properties

This function is ·deterministic·, ·context-dependent·, and ·focus-independent·. It depends on collations.

Rules

The second argument, $collation, defaults to ().

Supplying an empty sequence as $collation is equivalent to supplying fn:default-collation(). For more information on collations see 5.3.5 Choosing a collation.

The third argument defaults to the function data#1.

Let $modified-key be the function:


            function($item){
            $key($item) => fn:data() ! (
            if (. instance of xs:untypedAtomic)
            then xs:double(.)
            else .)
            }

That is, the supplied function for computing key values is wrapped in a function that converts any xs:untypedAtomic values in its result to xs:double. This makes the function consistent with the behavior of fn:min and fn:max, but inconsistent with fn:sort, which treats untyped values as strings.

The result of the function is obtained as follows:

  • If the input is an empty sequence, the result is an empty sequence.

  • The input sequence is sorted, by applying the function fn:sort($input, $collation, $modified-key).

  • Let $C be the selected collation, or the default collation where applicable.

  • Let $B be the first item in the sorted sequence.

  • The function returns those items $A from the input sequence such that (fn:deep-equal($key($A), $key($B), $C), retaining their order.

Error Conditions

If the set of computed keys contains xs:untypedAtomic values that are not castable to xs:double then operation will fail with a dynamic error ([err:FORG0001]FO).

If the set of computed keys contains values that are not comparable using the lt operator then the sort operation will fail with a type error ([err:XPTY0004]XP).

Examples
let $e := <a x="10" y="5" z="2"/>

The expression fn:lowest($e/@*) ! name() returns ("x"). (The attribute values are compared as strings).

The expression fn:lowest($e/@*, (), fn:number#1) ! name() returns ("z"). (Here the attribute values are compared as numbers).

The expression fn:lowest(("red", "green", "blue"), (), fn:string-length#1) returns ("red").

The expression fn:lowest(("red", "green", "blue"), (), map{"red": xs:hexBinary('FF0000'), "green": xs:hexBinary('008000'), "blue": xs:hexBinary('0000FF')}) returns ("blue").

The expression fn:lowest(("April", "June", "July", "August"), (), fn:string-length#1) returns ("June", "July").

The expression fn:lowest(1 to 25, (), ->{. idiv 10}) returns (1, 2, 3, 4, 5, 6, 7, 8, 9).

To find employees having the lowest salary:

fn:lowest($employees, (), ->{xs:decimal(salary)})
History

New in 4.0. Accepted 2022-09-20.

16.2.17 fn:apply

Summary

Makes a dynamic call on a function with an argument list supplied in the form of an array.

Signature
fn:apply(
$function as function(*),
$arguments as array(*)
) as item()*
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

The result of the function is obtained by invoking the supplied function $function with arguments taken from the members of the supplied array $arguments. The first argument of the function call is the first member of $arguments, the second argument is the second member of $array, and so on.

The arity of the supplied function $function must be the same as the size of the array $array.

The effect of calling fn:apply($f, [$a, $b, $c, ...]) is the same as the effect of the dynamic function call $f($a, $b, $c, ....). For example, the function conversion rules are applied to the supplied arguments in the usual way.

Error Conditions

A dynamic error is raised if the arity of the function $function is not the same as the size of the array $array ([err:FOAP0001]).

Notes

The function is useful where the arity of a function item is not known statically.

Examples

The expression fn:apply(fn:concat#3, ["a", "b", "c"]) returns "abc".

The expression fn:apply($f, array:subarray(["a", "b", "c", "d", "e", "f"], 1, fn:function-arity($f))) calls the supplied function $f supplying the number of arguments required by its arity.

16.3 Dynamic Loading

The following functions allow dynamic loading and execution of XQuery queries and XSLT stylesheets, or XPath operators.

Function Meaning
fn:load-xquery-module Provides access to the public functions and global variables of a dynamically loaded XQuery library module.
fn:transform Invokes a transformation using a dynamically loaded XSLT stylesheet.
fn:op Returns a function whose effect is to apply a supplied binary operator to two arguments.

16.3.1 fn:load-xquery-module

Summary

Provides access to the public functions and global variables of a dynamically loaded XQuery library module.

Signatures
fn:load-xquery-module(
$module-uri as xs:string
) as map(*)
fn:load-xquery-module(
$module-uri as xs:string,
$options as map(*)
) as map(*)
Properties

This function is ·deterministic·, ·context-dependent·, ·focus-independent·, and ·higher-order·.

Rules

The function loads an implementation-defined set of modules having the target namespace $module-uri.

Calling the one-argument version of the function has the same effect as calling the two-argument version with an empty map as the second argument.

The $options argument can be used to control the way in which the function operates. The ·option parameter conventions· apply.

Key Meaning
xquery-version The minimum level of the XQuery language that the processor must support.
  • Type: xs:decimal

  • Default: The version given in the prolog of the library module; or implementation-defined if this is absent.

location-hints A sequence of URIs (in the form of xs:string values) which may be used or ignored in an ·implementation-defined· way.
  • Type: xs:string*

  • Default: Empty sequence

context-item The item to be used as the initial context item when evaluating global variables in the library module. Supplying an empty sequence is equivalent to omitting the entry from the map, and indicates the absence of a context item. If the library module specifies a required type for the context item, then the supplied value must conform to this type, without conversion.
  • Type: item()?

  • Default: Absent

variables Values for external variables defined in the library module. Values must be supplied for external variables that have no default value, and may be supplied for external variables that do have a default value. The supplied value must conform to the required type of the variable, without conversion. The map contains one entry for each external variable: the key is the variable's name, and the associated value is the variable's value. The ·option parameter conventions· do not apply to this contained map.
  • Type: map(xs:QName, item()*)

  • Default: An empty map

vendor-options Values for vendor-defined configuration options for the XQuery processor used to process the request. The key is the name of an option, expressed as a QName: the namespace URI of the QName should be a URI controlled by the vendor of the XQuery processor. The meaning of the associated value is ·implementation-defined·. Implementations should ignore options whose names are in an unrecognized namespace. The ·option parameter conventions· do not apply to this contained map.
  • Type: map(xs:QName, item()*)

  • Default: An empty map

The result of the function is a map R with two entries:

  1. There is an entry whose key is the xs:string value "variables" and whose associated value is a map V. This map (V) contains one entry for each public global variable declared in the library module. The key of the entry is the name of the variable, as an xs:QName value; the associated value is the value of the variable.

  2. There is an entry whose key is the xs:string value "functions" and whose associated value is a map F. This map (F) contains one entry for each public function declared in the library module, except that when two functions have the same name (but different arity), they share the same entry. The key of the entry is the name of the function(s), as an xs:QName value; the associated value is a map A. This map (A) contains one entry for each function with the given name; its key is the arity of the function, as an xs:integer value, and its associated value is the function itself, as a function item. The function can be invoked using the rules for dynamic function invocation.

The static and dynamic context of the library module are established according to the rules in Section C Context Components XQ31.

It is ·implementation-defined· whether constructs in the library module are evaluated in the same ·execution scope· as the calling module.

The library module that is loaded may import other modules using an import module declaration. The result of fn:load-xquery-module does not include global variables or functions declared in such a transitively imported module. However, the options map supplied in the function call may (and if no default is defined, must) supply values for external variables declared in transitively loaded library modules.

The library module that is loaded may import schema declarations using an import schema declaration. It is ·implementation-defined· whether schema components in the in-scope schema definitions of the calling module are automatically added to the in-scope schema definitions of the dynamically loaded module. The in-scope schema definitions of the calling and called modules must be consistent, according to the rules defined in Section 2.2.5 Consistency Constraints XQ31.

Where nodes are passed to or from the dynamically loaded module, for example as an argument or result of a function, they should if possible retain their node identity, their base URI, their type annotations, and their relationships to all other nodes in the containing tree (including ancestors and siblings). If this is not possible, for example because the only way of passing nodes to the chosen XQuery implementation is by serializing and re-parsing, then a node may be passed in the form of a deep copy, which may lose information about the identity of the node, about its ancestors and siblings, about its base URI, about its type annotations, and about its relationships to other nodes passed across the interface.

Error Conditions

If $module-uri is a zero length string, a dynamic error is raised [err:FOQM0001].

If the implementation is not able to find a library module with the specified target namespace, an error is raised [err:FOQM0002].

If a static error (including a statically detected type error) is encountered when processing the library module, a dynamic error is raised [err:FOQM0003].

If a value is supplied for the initial context item or for an external variable and the value does not conform to the required type declared in the dynamically loaded module, a dynamic error is raised [err:FOQM0005].

If no suitable XQuery processor is available, a dynamic error is raised [err:FOQM0006]. This includes (but is not limited to) the following cases:

  1. No XQuery processor is available;

  2. Use of the function has been disabled;

  3. No XQuery processor supporting the requested version of XQuery is available;

  4. No XQuery processor supporting the optional Module Feature is available.

If a dynamic error (including a dynamically detected type error) is encountered when processing the module (for example, when evaluating its global variables), the dynamic error is returned as is.

Notes

As with all other functions in this specification, conformance requirements depend on the host language. For example, a host language might specify that provision of this function is optional, or that it is excluded entirely, or that implementations are required to support XQuery modules using a specified version of XQuery.

Even where support for this function is mandatory, it is recommended for security reasons that implementations should provide a user option to disable its use, or to disable aspects of its functionality.

16.3.2 fn:transform

Summary

Invokes a transformation using a dynamically loaded XSLT stylesheet.

Signature
fn:transform(
$options as map(*)
) as map(*)
Properties

This function is ·nondeterministic·, ·context-dependent·, and ·focus-independent·.

Rules

This function loads an XSLT stylesheet and invokes it to perform a transformation.

The inputs to the transformation are supplied in the form of a map. The ·option parameter conventions· apply to this map; they do not apply to any nested map unless otherwise specified.

The function first identifies the requested XSLT version, as follows:

  • If the xslt-version option is present, the requested XSLT version is the value of that option.

  • Otherwise, the requested XSLT version is the value of the [xsl:]version attribute of the outermost element in the supplied stylesheet or package.

The function then attempts to locate an XSLT processor that implements the requested XSLT version.

  • If a processor that implements the requested XSLT version is available, then it is used.

  • Otherwise, if a processor that implements a version later than the requested version is available, then it is used.

  • Otherwise, the function fails indicating that no suitable XSLT processor is available.

Note:

The phrase locate an XSLT processor includes the possibility of locating a software product and configuring it to act as an XSLT processor that implements the requested XSLT version.

If more than one XSLT processor is available under the above rules, then the one that is chosen may be selected according to the availability of requested features: see below.

Once an XSLT processor has been selected that implements a given version of XSLT, the processor follows the rules of that version of the XSLT specification. This includes any decision to operate in backwards or forwards compatibility mode. For example, if an XSLT 2.0 processor is selected, and the stylesheet specifies version="1.0", then the processor will operate in backwards compatibility mode; if the same processor is selected and the stylesheet specifies version="3.0", the processor will operate in forwards compatibility mode.

The combinations of options that are relevant to each version of XSLT, other than xslt-version itself, are listed below. This is followed by a table giving the meaning of each option.

  1. For invocation of an XSLT 1.0 processor (see [XSL Transformations (XSLT) Version 1.0]), the supplied options must include all of the following (if anything else is present, it is ignored):

    1. The stylesheet, provided by supplying exactly one of the following:

      stylesheet-location
      stylesheet-node
      stylesheet-text

    2. The source tree, provided as the value of the source-node option.

    3. Zero or more of the following additional options:

      stylesheet-base-uri
      stylesheet-params (defaults to an empty map)
      initial-mode (defaults to the unnamed mode)
      delivery-format (defaults to document)
      serialization-params (defaults to an empty map)
      enable-messages (default is implementation-defined)
      requested-properties (default is an empty map)
      vendor-options (defaults to an empty map)
      cache (default is implementation-defined)

  2. For invocation of an XSLT 2.0 processor (see [XSL Transformations (XSLT) Version 2.0]), the supplied options must include all of the following (if anything else is present, it is ignored):

    1. The stylesheet, provided by supplying exactly one of the following:

      stylesheet-location
      stylesheet-node
      stylesheet-text

    2. Invocation details, as exactly one of the following:

      1. For apply-templates invocation, all of the following:

        source-node

        Optionally, initial-mode (defaults to the unnamed mode)

      2. For call-template invocation, all of the following:

        initial-template

        Optionally, source-node

    3. Zero or more of the following additional options:

      stylesheet-base-uri
      stylesheet-params (defaults to an empty map)
      base-output-uri (defaults to absent)
      delivery-format (defaults to document)
      serialization-params (defaults to an empty map)
      enable-messages (default is implementation-defined)
      enable-trace (default is implementation-defined)
      requested-properties (default is an empty map)
      vendor-options (defaults to an empty map)
      cache (default is implementation-defined)

  3. For invocation of an XSLT 3.0 processor (see [XSL Transformations (XSLT) Version 4.0]), the supplied options must include all of the following (if anything else is present, it is ignored):

    1. The stylesheet, provided either by supplying exactly one of the following:

      stylesheet-location
      stylesheet-node
      stylesheet-text

      Or by supplying exactly one of the following:

      package-location
      package-node
      package-text
      package-name plus optionally package-version

    2. Invocation details, as exactly one of the following combinations:

      1. For apply-templates invocation, all of the following:

        Exactly one of source-node or initial-match-selection

        Optionally, initial-mode

        Optionally, template-params

        Optionally, tunnel-params

      2. For call-template invocation using an explicit template name, all of the following:

        initial-template

        Optionally, template-params

        Optionally, tunnel-params

        Optionally, source-node

      3. For call-template invocation using the defaulted template name xsl:initial-template, all of the following:

        Optionally, template-params

        Optionally, tunnel-params

        Note:

        If the source-node option is present and initial-template is absent, then apply-templates invocation will be used. To use call-template invocation on the template named xsl:initial-template while also supplying a context item for use when evaluating global variables, either (a) supply the context item using the global-context-item option, or (b) supply source-node, and set the initial-template option explicitly to the QName xsl:initial-template

      4. For call-function invocation, all of the following:

        initial-function

        function-params

      Note:

      The invocation method can be determined as the first of the following which applies:

      • If initial-function is present, then call-function invocation.

      • If initial-template is present, then call-template invocation.

      • If source-node or initial-match-selection is present, then apply-templates invocation.

      • Otherwise, call-template invocation using the default entry point xsl:initial-template.

    3. Zero or more of the following additional options:

      stylesheet-base-uri
      static-params (defaults to an empty map)
      stylesheet-params (defaults to an empty map)
      global-context-item (defaults to absent)
      base-output-uri (defaults to absent)
      delivery-format
      serialization-params (defaults to an empty map)
      enable-assertions (default is false)
      enable-messages (default is implementation-defined)
      enable-trace (default is implementation-defined)
      requested-properties (default is an empty map)
      vendor-options (defaults to an empty map)
      cache (default is implementation-defined)

The meanings of each option are defined in the table below.

Key Applies to Value Meaning
base-output-uri 1.0, 2.0, 3.0 The URI of the principal result document; also used as the base URI for resolving relative URIs of secondary result documents. If the value is a relative reference, it is resolved against the static base URI of the fn:transform function call.
  • Type: xs:string

  • Default: The effect of not supplying a base output URI is defined by the XSLT specification; the implementation may supply a default, for example the directory containing the stylesheet, or the current working directory.

cache 1.0, 2.0, 3.0 This option has no effect on the result of the transformation but may affect efficiency. The value true indicates an expectation that the same stylesheet is likely to be used for more than one transformation; the value false indicates an expectation that the stylesheet will be used once only.
  • Type: xs:boolean

  • Default: true()

delivery-format 1.0, 2.0, 3.0 The manner in which the transformation results should be delivered. Applies both to the principal result document and to secondary result documents created using xsl:result-document.
  • Type: xs:string

  • Default: document, unless the relevant xsl:output or xsl:result-document element specifies build-tree="no" (applies to XSLT 3.0 only), in which case the default is raw.

document The result is delivered as a document node.
serialized The result is delivered as a string, representing the results of serialization. Note that (as with the fn:serialize function) the final encoding stage of serialization (which turns a sequence of characters into a sequence of octets) is either skipped, or reversed by decoding the octet stream back into a character stream.
raw The result of the initial template or function is returned as an arbitrary XDM value (after conversion to the declared type, but without wrapping in a document node, and without serialization): when this option is chosen, the returned map contains the raw result.
enable-assertions 3.0 Indicates whether any xsl:assert instructions in the stylesheet are to be evaluated.
  • Type: xs:boolean

  • Default: false()

enable-messages 1.0, 2.0, 3.0 Indicates whether any xsl:message instructions in the stylesheet are to be evaluated. The destination and formatting of any such messages is implementation-defined.
  • Type: xs:boolean

  • Default: Implementation-defined

enable-trace 2.0, 3.0 Indicates whether any fn:trace functions in the stylesheet are to generate diagnostic messages. The destination and formatting of any such messages is implementation-defined.
  • Type: xs:boolean

  • Default: Implementation-defined

function-params 3.0 An array of values to be used as the arguments to the initial function call. The value is converted to the required type of the declared parameter using the function conversion rules.
  • Type: array(item()*)

  • Default: Empty array

global-context-item 3.0 The value of the global context item, as defined in XSLT 3.0
  • Type: item()

  • Default: The value of source-node

initial-function 3.0 The name of the initial function to be called for call-function invocation. The arity of the function is inferred from the length of function-params.
  • Type: xs:QName

  • Default: n/a

initial-match-selection 3.0 The value of the initial match selection, as defined in XSLT 3.0
  • Type: item()*

  • Default: The value of source-node

initial-mode 1.0, 2.0, 3.0 The name of the initial processing mode.
  • Type: xs:QName

  • Default:

initial-template 2.0, 3.0 The name of a named template in the stylesheet to act as the initial entry point.
  • Type: xs:QName

  • Default: xsl:initial-template

package-name 3.0 The name of the top-level stylesheet package to be invoked (an absolute URI)
  • Type: xs:string

  • Default: n/a

package-location 3.0 The location of the top-level stylesheet package, as a relative or absolute URI
  • Type: xs:string

  • Default: n/a

package-node 3.0 A document or element node containing the top-level stylesheet package
  • Type: node()

  • Default: n/a

package-text 3.0 The top-level stylesheet package in the form of unparsed lexical XML.
  • Type: xs:string

  • Default: n/a

package-version 3.0 The version of the top-level stylesheet package to be invoked.
  • Type: xs:string

  • Default: "*" (any version)

post-process 1.0 2.0 3.0 A function that is used to post-process each result document of the transformation (both the principal result and secondary results), in whatever form it would otherwise be delivered (document, serialized, or raw). The first argument of the function is the key used to identify the result in the map return by the fn:transform function (for example, this will be the supplied base output URI in the case of the principal result, or the string "output" if no base output URI was supplied). The second argument is the actual value. The value that is returned in the result of the fn:transform function is the result of applying this post-processing.

Note:

If the implementation provides a way of writing or invoking functions with side-effects, this post-processing function might be used to save a copy of the result document to persistent storage. For example, if the implementation provides access to the EXPath File library [EXPath], then a serialized document might be written to filestore by calling the file:write function. Similar mechanisms might be used to issue an HTTP POST request that posts the result to an HTTP server, or to send the document to an email recipient. The semantics of calling functions with side-effects are entirely ·implementation-defined·.

If the primary purpose of the post-processing function is achieved by means of such side-effects, and if the actual results are not needed by the caller of the fn:transform function, then it does not matter what the post-processing function actually returns (it could be an empty sequence, for example).

Calls to fn:transform can potentially have side-effects even in the absence of the post-processing option, because the XSLT specification allows a stylesheet to invoke extension functions that have side-effects. The semantics in this case are ·implementation-defined·.

  • Type: function(xs:string, item()*) as item()*

  • Default: function($a, $b) { $b }

requested-properties 1.0, 2.0, 3.0 The keys in the map are QNames that could legitimately be supplied in a call to the XSLT system-property function; the values in the map are the requested settings of the corresponding property. The boolean values true() and false() are equivalent to the string values yes and no. As a special case, setting a value for xsl:version has no effect, because of the potential for conflict with other options. For example:
  • Setting xsl:product-name to a particular value requests a particular XSLT software product.

  • Setting xsl:product-version requests a specific version of that product.

  • Setting xsl:is-schema-aware to true() requests a schema-aware processor.

  • Setting xsl:xsd-version to "1.1" requests a processor that supports XML Schema version 1.1.

Setting a boolean property such as xsl:supports-dynamic-evaluation to false() is interpreted as an explicit request for a processor in which the value of the property is false. The effect if the requests cannot be precisely met is implementation-defined. In some cases it may be appropriate to ignore the request or to provide an alternative (for example, a later version of the product than the one requested); in other cases it may be more appropriate to raise an error [err:FOXT0001] indicating that no suitable XSLT processor is available.
  • Type: map(xs:QName, xs:anyAtomicType)

  • Default: Empty map

serialization-params 1.0, 2.0, 3.0 Serialization parameters for the principal result document. The supplied map follows the same rules that apply to a map supplied as the second argument of fn:serialize.
  • When a parameter is supplied, the corresponding value overrides or augments the value specified in the unnamed xsl:output declaration (or its default), following the same rules as when one xsl:output declaration overrides another with lower import precedence.

  • When a parameter is supplied and the corresponding value is an empty sequence (for example, map{"standalone":()}), any value specified in the unnamed xsl:output declaration is overridden by the default value.

  • When a parameter is not supplied in serialization-params (that is, when the key is absent) the value that applies is the value appearing in the unnamed xsl:output declaration, or its default.

  • Type: map(xs:anyAtomicType, item()*)

  • Default: Empty map

source-node 1.0, 2.0, 3.0 When source-node is supplied then the global-context-item (the context item for evaluating global variables) is the root of the tree containing the supplied node. In addition, for apply-templates invocation, the source-node acts as the initial-match-selection, that is, stylesheet execution starts by applying templates to this node.
  • Type: node()

  • Default: n/a

static-params 3.0 The values of static parameters defined in the stylesheet; the keys are the names of the parameters, and the associated values are their values. The value is converted to the required type of the declared parameter using the function conversion rules.
  • Type: map(xs:QName, item()*)

  • Default: Empty map

stylesheet-base-uri 1.0, 2.0, 3.0 A string intended to be used as the static base URI of the principal stylesheet module. This value must be used if no other static base URI is available. If the supplied stylesheet already has a base URI (which will generally be the case if the stylesheet is supplied using stylesheet-node or stylesheet-location) then it is ·implementation-defined· whether this parameter has any effect. If the value is a relative reference, it is resolved against the static base URI of the fn:transform function call.
  • Type: xs:string

  • Default: n/a

stylesheet-location 1.0, 2.0, 3.0 URI that can be used to locate the principal stylesheet module. If relative, it is resolved against the static base URI of the fn:transform function call. The value also acts as the default for stylesheet-base-uri.
  • Type: xs:string

  • Default: n/a

stylesheet-node 1.0, 2.0, 3.0 Root of the tree containing the principal stylesheet module, as a document or element node. The base URI of the node acts as the default for stylesheet-base-uri.
  • Type: node()

  • Default: n/a

stylesheet-params 1.0, 2.0, 3.0 A map holding values to be supplied for stylesheet parameters. The keys are the parameter names; the values are the corresponding parameter values. The values are converted if necessary to the required type using the function conversion rules. The default is an empty map.
  • Type: map(xs:QName, item()*)

  • Default: Empty map

stylesheet-text 1.0, 2.0, 3.0 The principal stylesheet module in the form of unparsed lexical XML.
  • Type: xs:string

  • Default: n/a

template-params 3.0 The values of non-tunnel parameters to be supplied to the initial template, used with both apply-templates and call-template invocation. Each value is converted to the required type of the declared parameter using the function conversion rules.
  • Type: map(xs:QName, item()*)

  • Default:

tunnel-params 3.0 The values of tunnel parameters to be supplied to the initial template, used with both apply-templates and call-template invocation. Each value is converted to the required type of the declared parameter using the function conversion rules.
  • Type: map(xs:QName, item()*)

  • Default: Empty map

vendor-options 1.0, 2.0, 3.0 Values for vendor-defined configuration options for the XSLT processor used to process the request. The key is the name of an option, expressed as a QName: the namespace URI of the QName should be a URI controlled by the vendor of the XSLT processor. The meaning of the associated value is ·implementation-defined·. Implementations should ignore options whose names are in an unrecognized namespace. Default is an empty map.
  • Type: map{xs:QName, item()*}

  • Default: Empty map

xslt-version 1.0, 2.0, 3.0 The minimum level of the XSLT language that the processor must support.
  • Type: xs:decimal

  • Default: The [xsl:]version attribute at the outermost level of the stylesheet.

The result of the transformation is returned as a map. There is one entry in the map for the principal result document, and one for each secondary result document. The key is a URI in the form of an xs:string value. The key for the principal result document is the base output URI if specified, or the string "output" otherwise. The key for secondary result documents is the URI of the document, as an absolute URI. The associated value in each entry depends on the requested delivery format. If the delivery format is document, the value is a document node. If the delivery format is serialized, the value is a string containing the serialized result.

Where nodes are passed to or from the transformation, for example as the value of a stylesheet parameter or the result of a function, they should if possible retain their node identity, their base URI, their type annotations, and their relationships to all other nodes in the containing tree (including ancestors and siblings). If this is not possible, for example because the only way of passing nodes to the chosen XSLT implementation is by serializing and re-parsing, then a node may be passed in the form of a deep copy, which may lose information about the identity of the node, about its ancestors and siblings, about its base URI, about its type annotation, and about its relationships to other nodes passed across the interface.

It is ·implementation-defined· whether the XSLT transformation is executed within the same ·execution scope· as the calling code.

The function is ·nondeterministic· in that it is ·implementation-dependent· whether running the function twice against the same inputs produces identical results. The results of two invocations may differ in the identity of any returned nodes; they may also differ in other respects, for example because the value of fn:current-dateTime is different for the two invocations, or because the contents of external documents accessed using fn:doc or xsl:source-document change between one invocation and the next.

Error Conditions

A dynamic error is raised [err:FOXT0001] if the transformation cannot be invoked because no suitable XSLT processor is available. This includes (but is not limited to) the following cases:

  1. No XSLT processor is available;

  2. No XSLT processor supporting the requested version of XSLT is available;

  3. The XSLT processor API does not support some requested feature (for example, the ability to supply tunnel parameters externally);

A dynamic error is raised [err:FOXT0002] if an error is detected in the supplied parameters (for example if two mutually exclusive parameters are supplied).

If a static or dynamic error is reported by the XSLT processor, this function fails with a dynamic error, retaining the XSLT error code.

A dynamic error is raised [err:FOXT0003] if the XSLT transformation invoked by a call on fn:transform fails with a static or dynamic error, and no more specific error code is available.

Note:

XSLT 1.0 does not define any error codes, so this is the likely outcome with an XSLT 1.0 processor. XSLT 2.0 and 3.0 do define error codes, but some APIs do not expose them. If multiple errors are signaled by the transformation (which is most likely to happen with static errors) then the error code should where possible be that of one of these errors, chosen arbitrarily; the processor may make details of additional errors available to the application in an ·implementation-defined· way.

A dynamic error is raised [err:FOXT0004] if the use of this function (or of selected options) has been externally disabled, for example for security reasons.

A dynamic error is raised [err:FOXT0006] if the transformation produces output containing characters available only in XML 1.1, and the calling processor cannot handle such characters.

Recursive use of the fn:transform function may lead to catastrophic failures such as non-termination or stack overflow. No error code is assigned to such conditions, since they cannot necessarily be detected by the processor.

Notes

As with all other functions in this specification, conformance requirements depend on the host language. For example, a host language might specify that provision of this function is optional, or that it is excluded entirely, or that implementations are required to support a particular set of values for the xslt-version parameter.

Even where support for this function is mandatory, it is recommended for security reasons that implementations should provide a user option to disable its use, or to disable aspects of its functionality such as the ability to write to persistent resources.

Examples

The following example loads a stylesheet from the location render.xsl, applies it to a document loaded from test.xml, and uses an XPath expression to examine the result:

let $result := fn:transform(
  map {
    "stylesheet-location" : "render.xsl",
    "source-node"    : fn:doc('test.xml')
  })
return $result?output//body  
               

16.3.3 fn:op

Summary

Returns a function whose effect is to apply a supplied binary operator to two arguments.

Signature
fn:op(
$operator as xs:string
) as function(item()*, item()*) as item()*
Properties

This function is ·deterministic·, ·context-independent·, ·focus-independent·, and ·higher-order·.

Rules

The supplied operator must be one of the following:

",", "and", "or", "+", "-", "*", "div", "idiv", "mod", "=", "<", "<=", ">", ">=", "!=", "eq", "lt", "le", "gt", "ge", "ne", "<<", ">>", "is", "||", "|", "union", "except", "intersect", "to", "otherwise"

The result of calling fn:op("⊙"), where is one of the above operators, is the function represented by the XPath expression:

function($x, $y) { $x ⊙ $y }

For example, op("+") returns function($x, $y) { $x + $y }.

Error Conditions

A dynamic error is raised if the supplied argument is not one of the supported operators ([TODO: error code]).

Notes

The function is useful in contexts where an arity-2 callback function needs to be supplied, and a standard operator meets the requirement.

For example, the XSLT xsl:map instruction has an on-duplicates attribute that expects such a function. Specifying on-duplicates="op(',')" is equivalent to specifying on-duplicates="function($x, $y) { $x, $y }

The function is also useful in cases where the choice of operator to apply is made dynamically.

Examples

The expression fn:for-each-pair(21 to 25, 1 to 5, fn:op("+")) returns 22, 24, 26, 28, 30.

The expression fn:for-each-pair(21 to 25, 1 to 5, fn:op("-")) returns 20, 20, 20, 20, 20.

History

New in 4.0. Accepted 2022-10-11.