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


4 Processing numerics

This section specifies arithmetic operators on the numeric datatypes defined in [XML Schema Part 2: Datatypes Second Edition].

4.4 Functions on numeric values

The following functions are defined on numeric types. Each function returns a value of the same type as the type of its argument.

  • If the argument is the empty sequence, the empty sequence is returned.

  • For xs:float and xs:double arguments, if the argument is NaN, NaN is returned.

  • With the exception of fn:abs, functions with arguments of type xs:float and xs:double that are positive or negative infinity return positive or negative infinity.

FunctionMeaning
fn:absReturns the absolute value of $value.
fn:ceilingRounds $value upwards to a whole number.
fn:floorRounds $value downwards to a whole number.
fn:roundRounds a value to a specified number of decimal places, with control over how the rounding takes place.
fn:round-half-to-evenRounds a value to a specified number of decimal places, rounding to make the last digit even if two such values are equally near.
fn:divide-decimalsDivides one xs:decimal by another to a defined precision, returning both the quotient and the remainder.
fn:is-NaNReturns true if the argument is the xs:float or xs:double value NaN.

Note:

The fn:round function has been extended with a third argument in version 4.0 of this specification; this means that the fn:ceiling, fn:floor, and fn:round-half-to-even functions are now technically redundant. They are retained, however, both for backwards compatibility and for convenience.

4.4.4 fn:round

Changes in 4.0  

  1. A third argument has been added, providing control over the rounding mode.  [Issues 1187 1274 PRs 1260 1275 11 June 2024]

  2. It is explicitly stated that the limits for $precision are implementation-defined.  [Issue 1705  PR 1711 1 January 2025]

Summary

Rounds a value to a specified number of decimal places, with control over how the rounding takes place.

Signature
fn:round(
$valueas xs:numeric?,
$precisionas xs:integer?:= 0,
$modeas enum('floor', 'ceiling', 'toward-zero', 'away-from-zero', 'half-to-floor', 'half-to-ceiling', 'half-toward-zero', 'half-away-from-zero', 'half-to-even')?:= 'half-to-ceiling'
) as xs:numeric?
Properties

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

Rules

General rules: see 4.4 Functions on numeric values.

The function returns a value that is close to $value and that is a multiple of ten to the power of minus $precision. The default value of $precision is zero, in which case the function returns a whole number (but not necessarily an xs:integer).

The detailed way in which rounding is performed depends on the value of $mode, as follows. Here L means the highest multiple of ten to the power of minus $precision that is less than or equal to $value, U means the lowest multiple of ten to the power of minus $precision that is greater than or equal to $value, N means the multiple of ten to the power of minus $precision that is numerically closest to $value, and midway means that $value is equal to the arithmetic mean of L and U.

Rounding Modes
Rounding ModeMeaning

'floor'

Returns L.

'ceiling'

Returns U.

'toward-zero'

Returns L if $value is positive, otherwise U.

'away-from-zero'

Returns U if $value is positive, otherwise L

'half-to-floor'

Returns N, unless midway, in which case L.

'half-to-ceiling'

Returns N, unless midway, in which case U. This is the default.

'half-toward-zero'

Returns N, unless midway, in which case it returns L if $value is positive, otherwise U.

'half-away-from-zero'

Returns N, unless midway, in which case it returns U if $value is positive, otherwise L.

'half-to-even'

Returns N, unless midway, in which case it returns whichever of L and U has a last significant digit that is even.

For the four types xs:float, xs:double, xs:decimal and xs:integer, it is guaranteed that if the type of $value is an instance of type T then the result will also be an instance of T. The result may also be an instance of a type derived from one of these four by restriction. For example, if $value is an instance of xs:decimal and $precision is less than one, then the result may be an instance of xs:integer.

If the second argument is omitted or is an empty sequence, the function produces the same result as when $precision = 0 (that is, it rounds to a whole number).

When $value is of type xs:float and xs:double:

  1. If $value is NaN, positive or negative zero, or positive or negative infinity, then the result is the same as the argument.

  2. For other values, the argument is cast to xs:decimal using an implementation of xs:decimal that imposes no limits on the number of digits that can be represented. The function is applied to this xs:decimal value, and the resulting xs:decimal is cast back to xs:float or xs:double as appropriate to form the function result. If the resulting xs:decimal value is zero, then positive or negative zero is returned according to the sign of $value.

There may be implementation-defined limits on the precision available. If the requested $precision is outside this range, it should be adjusted to the nearest value supported by the implementation.

Notes

This function is typically used with a non-zero $precision in financial applications where the argument is of type xs:decimal. For arguments of type xs:float and xs:double the results may be counter-intuitive. For example, consider round(35.425e0, 2). The result is not 35.43, as might be expected, but 35.42. This is because the xs:double written as 35.425e0 has an exact value equal to 35.42499999999..., which is closer to 35.42 than to 35.43.

The call round($v, 0, "floor") is equivalent to floor($v).

The call round($v, 0, "ceiling") is equivalent to ceiling($v).

The call round($v, $p, "half-to-even") is equivalent to round-half-to-even($v, $p).

Examples
ExpressionResult
round(2.5)
3.0
round(2.4999)
2.0
round(-2.5)
-2.0
round(1.125, 2)
1.13
round(8452, -2)
8500
round(3.1415e0, 2)
3.14e0
math:log(0) => round()
-xs:double('INF')
round(1.7, 0, "floor")
1
round(-1.7, 0, "floor")
-2
round(1.7, 0, "ceiling")
2
round(-1.7, 0, "ceiling")
-1
round(1.7, 0, "toward-zero")
1
round(-1.7, 0, "toward-zero")
-1
round(1.7, 0, "away-from-zero")
2
round(-1.7, 0, "away-from-zero")
-2
round(1.125, 2, "half-to-floor")
1.12
round(-1.125, 2, "half-to-floor")
-1.13
round(1.125, 2, "half-to-ceiling")
1.13
round(-1.125, 2, "half-to-ceiling")
-1.12
round(1.125, 2, "half-toward-zero")
1.12
round(-1.125, 2, "half-toward-zero")
-1.12
round(1.125, 2, "half-away-from-zero")
1.13
round(-1.125, 2, "half-away-from-zero")
-1.13
round(1.125, 2, "half-to-even")
1.12
round(-1.125, 2, "half-to-even")
-1.12

4.4.5 fn:round-half-to-even

Changes in 4.0  

  1. It is explicitly stated that the limits for $precision are implementation-defined.  [Issue 1705  PR 1711 1 January 2025]

Summary

Rounds a value to a specified number of decimal places, rounding to make the last digit even if two such values are equally near.

Signature
fn:round-half-to-even(
$valueas xs:numeric?,
$precisionas xs:integer?:= 0
) as xs:numeric?
Properties

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

Rules

General rules: see 4.4 Functions on numeric values.

The function returns the nearest (that is, numerically closest) value to $value that is a multiple of ten to the power of minus $precision. If two such values are equally near (e.g. if the fractional part in $value is exactly .500...), the function returns the one whose least significant digit is even.

For the four types xs:float, xs:double, xs:decimal and xs:integer, it is guaranteed that if the type of $value is an instance of type T then the result will also be an instance of T. The result may also be an instance of a type derived from one of these four by restriction. For example, if $value is an instance of xs:decimal and $precision is less than one, then the result may be an instance of xs:integer.

If the second argument is omitted or an empty sequence, the function produces the same result as the two-argument version with $precision = 0.

For arguments of type xs:float and xs:double:

  1. If the argument is NaN, positive or negative zero, or positive or negative infinity, then the result is the same as the argument.

  2. In all other cases, the argument is cast to xs:decimal using an implementation of xs:decimal that imposes no limits on the number of digits that can be represented. The function is applied to this xs:decimal value, and the resulting xs:decimal is cast back to xs:float or xs:double as appropriate to form the function result. If the resulting xs:decimal value is zero, then positive or negative zero is returned according to the sign of the original argument.

There may be implementation-defined limits on the precision available. If the requested $precision is outside this range, it should be adjusted to the nearest value supported by the implementation.

Notes

This function is typically used in financial applications where the argument is of type xs:decimal. For arguments of type xs:float and xs:double the results may be counter-intuitive. For example, consider round-half-to-even(xs:float(150.015), 2). The result is not 150.02 as might be expected, but 150.01. This is because the conversion of the xs:float value represented by the literal 150.015 to an xs:decimal produces the xs:decimal value 150.014999389..., which is closer to 150.01 than to 150.02.

From 4.0, the effect of this function can also be achieved by calling fn:round with the third argument set to "half-to-even".

Examples
ExpressionResult
round-half-to-even(0.5)
0.0
round-half-to-even(1.5)
2.0
round-half-to-even(2.5)
2.0
round-half-to-even(3.567812e+3, 2)
3567.81e0
round-half-to-even(4.7564e-3, 2)
0.0e0
round-half-to-even(35612.25, -2)
35600
math:log(0) => round-half-to-even()
-xs:double('INF')

4.4.6 fn:divide-decimals

Changes in 4.0  

  1. New in 4.0.  [Issue 1261  PR 1671 1 January 2025]

Summary

Divides one xs:decimal by another to a defined precision, returning both the quotient and the remainder.

Signature
fn:divide-decimals(
$valueas xs:decimal,
$divisoras xs:decimal,
$precisionas xs:integer?:= 0
) as record(quotient as xs:decimal, remainder as xs:decimal)
Properties

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

Rules

The function returns a record with two fields:

  1. quotient is the xs:decimal value furthest from zero such that:

    1. quotient is an exact multiple of ten to the power of minus $precision;

    2. the absolute value of quotient multipled by $divisor is less than or equal to the absolute value of $value;

    3. the sign of quotient is the same as the sign of op:numeric-divide($value, $divisor).

  2. remainder is the exact result of subtracting quotient multiplied by $divisor from $value.

There may be implementation-defined limits on the precision available. If the requested $precision is outside this range, it should be adjusted to the nearest value supported by the implementation.

Error Conditions

A dynamic error is raised [err:FOAR0001] if $divisor is zero.

Examples
ExpressionResult
divide-decimals(120.6, 60.3, 4)
{ "quotient": 2, "remainder": 0 }
divide-decimals(10, 3)
{ "quotient": 3, "remainder": 1 }
divide-decimals(10, -3)
{ "quotient": -3, "remainder": 1 }
divide-decimals(-10, 3)
{ "quotient": -3, "remainder": -1 }
divide-decimals(-10, -3)
{ "quotient": 3, "remainder": -1 }
divide-decimals(10, 3, 6)
{ "quotient": 3.333333, "remainder": 0.000001 }
divide-decimals(100, 30)
{ "quotient": 3, "remainder": 10 }
divide-decimals(150_862, 7, -3)
{ "quotient": 21_000, "remainder": 3_862 }

6 Regular expressions

The functions described in this section make use of a regular expression syntax for pattern matching. The syntax and semantics of regular expressions are defined in this section.

6.3 Functions using regular expressions

FunctionMeaning
fn:matchesReturns true if the supplied string matches a given regular expression.
fn:replaceReturns a string produced from the input string by replacing any segments that match a given regular expression with a supplied replacement string, provided either literally, or by invoking a supplied function.
fn:tokenizeReturns a sequence of strings constructed by splitting the input wherever a separator is found; the separator is any substring that matches a given regular expression.
fn:analyze-stringAnalyzes a string using a regular expression, returning an XML structure that identifies which parts of the input string matched or failed to match the regular expression, and in the case of matched substrings, which substrings matched each capturing group in the regular expression.

6.3.2 fn:replace

Changes in 4.0  

  1. The $replacement argument can now be a function that computes the replacement strings.  [Issue 1876 PR 1897 8 April 2025]

  2. It is now permitted for the regular expression to match a zero-length string.  [ PR 1856]

Summary

Returns a string produced from the input string by replacing any segments that match a given regular expression with a supplied replacement string, provided either literally, or by invoking a supplied function.

Signature
fn:replace(
$valueas xs:string?,
$patternas xs:string,
$replacementas (xs:string | fn(xs:untypedAtomic, xs:untypedAtomic*) as item()?)?:= (),
$flagsas xs:string?:= ''
) as xs:string
Properties

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

Rules

If $value is the empty sequence, it is interpreted as the zero-length string.

If the $flags argument is omitted or if it is an empty sequence, the effect is the same as setting $flags to a zero-length string. Flags are defined in 6.2 Flags.

The string $value is matched against the regular expression $pattern, using the supplied $flags, to obtain a set of disjoint matching segments. A replacement string R for each of these segments (say M) is determined by the value of the $replacement argument, by applying the first of the following rules that applies:

  • If $replacement is absent or empty, R is a zero-length string.

  • If $replacement is a function item F, then R is obtained by calling F, and then applying the function fn:string to the result.

    The first argument to F is the string to be replaced, provided as xs:untypedAtomic.

    The second argument to F provides the captured groups as an xs:untypedAtomic sequence. The Nth item in this sequence is the string value of the segment captured by the Nth capturing subexpression. If the Nth capturing subexpression was not matched, the Nth item will be the zero-length string.

    Note that the rules for function coercion mean that the function actually supplied for F may be an arity-1 function: the second argument does not need to be declared if it is not used.

  • If $replacement is a string and the q flag is present, R is the value of $replacement.

  • Otherwise, the value of $replacement is processed as follows.

    Within the supplied $replacement string, a variable marker $N (where N is an unsigned integer) may be used to refer to the Nth captured group associated with M. The replacement string R is obtained by replacing each of these variable markers with the string value of the relevant captured group. The variable marker $0 refers to the substring captured by the regular expression as a whole.

    A literal $ character within the replacement string must be written as \$, and a literal \ character must be written as \\.

    More specifically, the rules are as follows, where S is the number of capturing subexpressions in the regular expression, and N is the decimal number formed by taking all the digits that consecutively follow the $ character in $replacement:

    1. If N=0, then the variable is replaced by the string value of M.

    2. If 1<=N<=S, then the variable marker is replaced by the string value of the Nth captured group associated with M. If the Nth parenthesized sub-expression was not matched, then the variable marker is replaced by the zero-length string.

    3. If S<N<=9, then the variable marker is replaced by the zero-length string.

    4. Otherwise (if N>S and N>9), the last digit of N is taken to be a literal character to be included “as is” in the replacement string, and the rules are reapplied using the number N formed by stripping off this last digit.

      For example, if the replacement string is "$23" and there are 5 substrings, the result contains the value of the substring that matches the second capturing subexpression, followed by the digit 3.

The function returns the xs:string that is obtained by replacing each of the disjoint matching segments of $value with the corresponding value of R.

Error Conditions

A dynamic error is raised [err:FORX0002] if the value of $pattern is invalid according to the rules described in section 6.1 Regular expression syntax.

A dynamic error is raised [err:FORX0001] if the value of $flags is invalid according to the rules described in section 6.2 Flags.

In the absence of the q flag, a dynamic error is raised [err:FORX0004] if the value of $replacement contains a dollar sign ($) character that is not immediately followed by a digit 0-9 and not immediately preceded by a backslash (\).

In the absence of the q flag, a dynamic error is raised [err:FORX0004] if the value of $replacement contains a backslash (\) character that is not part of a \\ pair, unless it is immediately followed by a dollar sign ($) character.

A dynamic error is raised [err:FORX0005] if both the $replacement and $action arguments are supplied, and neither is an empty sequence.

Notes

If the input string contains no substring that matches the regular expression, the result of the function is a single string identical to the input string.

If two overlapping substrings of $value both match the $pattern, then only the first one (that is, the one whose first character comes first in the $value string) is replaced.

If two alternatives within the pattern both match at the same position in the $input, then the match that is chosen is the one matched by the first alternative. For example:

 replace("abcd", "(ab)|(a)", "[1=$1][2=$2]") returns "[1=ab][2=]cd"

The rules for disjoint matching segments allow a zero-length matching segment to immediately follow a non-zero-length matching segment (they are not considered to overlap). This means, for example, that the regular expression .* will typically produce two matches: one matching segment containing all the characters in the input string, and a second zero-length matching seqment at the end position of the string.

Examples
Expression:

replace("abracadabra", "bra", "*")

Result:
"a*cada*"
Expression:

replace("abracadabra", "a.*a", "*")

Result:
"*"
Expression:

replace("abracadabra", "a.*?a", "*")

Result:
"*c*bra"
Expression:

replace("abracadabra", "a", "")

Result:
"brcdbr"
Expression:

replace("abracadabra", "a(.)", "a$1$1")

Result:
"abbraccaddabbra"
Expression:

replace("AAAA", "A+", "b")

Result:
"b"
Expression:

replace("AAAA", "A+?", "b")

Result:
"bbbb"
Expression:

replace("In the beginning was the Word", "\b", "|")

Result:
"|In| |the| |beginning| |was| |the| |Word|"
Expression:

replace("abcd!", "[a-z](?=.*(.)$)", "$0$1")

Result:
"a!b!c!d!!"
Expression:

replace("darted", "^(.*?)d(.*)$", "$1c$2")

Result:
"carted"

(Only the first d is replaced.)

Expression:
replace("abracadabra", "bra", upper-case#1)
Result:
"aBRAcadaBRA"
Expression:
replace("Chapter 9", "[0-9]+", fn { . + 1 })
Result:
"Chapter 10"
Expression:
replace(
  "LHR to LAX",
  "\b[A-Z]{3}\b",
  { 'LAX': 'Los Angeles', 'LHR': 'London' }
)
Result:
"London to Los Angeles"
Expression:
replace(
  "57°43′30″",
  "([0-9]+)°([0-9]+)′([0-9]+)″",
  fn($s, $groups) {
    string($groups[1] + $groups[2] ÷ 60 + $groups[3] ÷ 3600) || '°'
  }
)
Result:
"57.725°"

14 Processing sequences

A sequence is an ordered collection of zero or more items. An item is a node, an atomic item, or a function, such as a map or an array. The terms sequence and item are defined formally in [XQuery 4.0: An XML Query Language] and [XML Path Language (XPath) 4.0].

14.1 General functions and operators on sequences

The following functions are defined on sequences. These functions work on any sequence, without performing any operations that are sensitive to the individual items in the sequence.

FunctionMeaning
fn:emptyReturns true if the argument is the empty sequence.
fn:existsReturns true if the argument is a non-empty sequence.
fn:footReturns the last item in a sequence.
fn:headReturns the first item in a sequence.
fn:identityReturns its argument value.
fn:insert-beforeReturns a sequence constructed by inserting an item or a sequence of items at a given position within an existing sequence.
fn:items-atReturns a sequence containing the items from $input at positions defined by $at, in the order specified.
fn:removeReturns a new sequence containing all the items of $inputexcept those at specified positions.
fn:replicateProduces multiple copies of a sequence.
fn:reverseReverses the order of items in a sequence.
fn:sequence-joinInserts a separator between adjacent items in a sequence.
fn:sliceReturns a sequence containing selected items from a supplied input sequence based on their position.
fn:subsequenceReturns the contiguous sequence of items in $input beginning at the position indicated by $start and continuing for the number of items indicated by $length.
fn:tailReturns all but the first item in a sequence.
fn:trunkReturns all but the last item in a sequence.
fn:unorderedReturns the items of $input in an implementation-dependent order.
fn:voidAbsorbs the argument.

As in the previous section, for the illustrative examples below, assume an XQuery or transformation operating on a non-empty Purchase Order document containing a number of line-item elements. The variable $seq is bound to the sequence of line-item nodes in document order. The variables $item1, $item2, etc. are bound to separate, individual line-item nodes in the sequence.

14.1.5 fn:identity

Changes in 4.0  

  1. New in 4.0  [Issue 858  PR 1473 20 September 2022]

Summary

Returns its argument value.

Signature
fn:identity(
$inputas item()*
) as item()*
Properties

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

Rules

The function returns $input.

Formal Equivalent

The effect of the function is equivalent to the result of the following XPath expression.

$input
Notes

The function is useful in contexts where a function must be supplied, but no processing is required.

Examples
ExpressionResult
identity(0)
0
identity(1 to 10)
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
parse-xml('<a/>') ! (identity(/) is /)
true()

(If the argument is a node, the function returns the identical node, not a copy).

identity(())
()

14.2 Comparison functions

The functions in this section perform comparisons between the items in one or more sequences.

FunctionMeaning
fn:atomic-equalDetermines whether two atomic items are equal, under the rules used for comparing keys in a map.
fn:deep-equal This function assesses whether two sequences are deep-equal to each other. To be deep-equal, they must contain items that are pairwise deep-equal; and for two items to be deep-equal, they must either be atomic items that compare equal, or nodes of the same kind, with the same name, whose children are deep-equal, or maps with matching entries, or arrays with matching members.
fn:compareReturns -1, 0, or 1, depending on whether the first value is less than, equal to, or greater than the second value.
fn:distinct-valuesReturns the values that appear in a sequence, with duplicates eliminated.
fn:duplicate-valuesReturns the values that appear in a sequence more than once.
fn:index-ofReturns a sequence of positive integers giving the positions within the sequence $input of items that are equal to $target.
fn:starts-with-subsequenceDetermines whether one sequence starts with another, using a supplied callback function to compare items.
fn:ends-with-subsequenceDetermines whether one sequence ends with another, using a supplied callback function to compare items.
fn:contains-subsequenceDetermines whether one sequence contains another as a contiguous subsequence, using a supplied callback function to compare items.

14.2.3 fn:compare

Changes in 4.0  

  1. The function has been expanded in scope to handle comparison of values other than strings.  [Issue 893 PR 909 10 January 2024]

  2. The spec has been corrected to note that the function depends on the implicit timezone.  [Issue 1608  PR 1611 26 November 2024]

Summary

Returns -1, 0, or 1, depending on whether the first value is less than, equal to, or greater than the second value.

Signature
fn:compare(
$value1as xs:anyAtomicType?,
$value2as xs:anyAtomicType?,
$collationas xs:string?:= fn:default-collation()
) as xs:integer?
Properties

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

The three-argument form of this function is deterministic, context-dependent, and focus-independent. It depends on collations, and implicit timezone, and static base URI.

Rules

Compares two atomic items $value1 and $value2 for order, and returns the integer value -1, 0, or 1, depending on whether $value1 is less than, equal to, or greater than $value2, respectively.

This function differs from the operators lt, eq, and gt in that decimal values are not converted to doubles. This means that the comparison is fully transitive, which makes it safe for use in sorting algorithms. It is used to underpin sorting in XQuery 4.0 and XSLT 4.0, and is also available as a free-standing function in its own right.

If either $value1 or $value2 is the empty sequence, the function returns the empty sequence.

Otherwise, the result is determined as follows:

  1. If $value1 is an instance of xs:string, xs:anyURI or xs:untypedAtomic, and if $value2 is an instance of xs:string, xs:anyURI or xs:untypedAtomic, the values are compared as strings, and the result reflects the order according to the rules of the collation that is used.

    The collation is determined according to the rules in 5.3.6 Choosing a collation.

    When used with the default collation, the function defines the semantics of the eq, ne, gt, lt, le and ge operators on xs:string values.

  2. If both $value1 and $value2 are instances of xs:numeric, the function relies on a total order, which is defined as follows:

    1. A value $f of type xs:float is in all cases equal to the value xs:double($f). The remaining rules therefore only consider instances of xs:double and xs:decimal.

    2. NaN is equal to itself and less than any other value.

    3. Negative infinity is equal to itself and less than any other value except NaN.

    4. Positive infinity is equal to itself and greater than any other value.

    5. Negative zero is equal to positive zero.

    6. Other xs:double and xs:decimal values (that is, values other than the infinities, NaN, and negative zero) are ordered according to their mathematical magnitude, the comparison being done without any rounding or loss of precision. This effect can be achieved by converting xs:double values to xs:decimal using an implementation of xs:decimal that imposes no limits on precision or scale, or an implementation whose limits are such that all xs:double values can be represented precisely.

  3. If both $value1 and $value2 are instances of xs:boolean, then:

    1. -1 is returned if op:boolean-less-than($value1, $value2) returns true.

    2. 0 is returned if op:boolean-equal($value1, $value2) returns true.

    3. 1 is returned otherwise.

  4. If $value1 is an instance of xs:hexBinary or xs:base64Binary, and if $value2 is an instance of xs:hexBinary or xs:base64Binary, then:

    1. -1 is returned if op:binary-less-than($value1, $value2) returns true.

    2. 0 is returned if op:binary-equal($value1, $value2) returns true.

    3. 1 is returned otherwise.

  5. If both $value1 and $value2 are instances of xs:date, then:

    1. -1 is returned if op:date-less-than($value1, $value2) returns true.

    2. 0 is returned if op:date-equal($value1, $value2) returns true.

    3. 1 is returned otherwise.

  6. If both $value1 and $value2 are instances of xs:time, then:

    1. -1 is returned if op:time-less-than($value1, $value2) returns true.

    2. 0 is returned if op:time-equal($value1, $value2) returns true.

    3. 1 is returned otherwise.

  7. If both $value1 and $value2 are instances of xs:dateTime, then:

    1. -1 is returned if op:dateTime-less-than($value1, $value2) returns true.

    2. 0 is returned if op:dateTime-equal($value1, $value2) returns true.

    3. 1 is returned otherwise.

  8. If both $value1 and $value2 are instances of xs:dayTimeDuration, then:

    1. -1 is returned if op:dayTimeDuration-less-than($value1, $value2) returns true.

    2. 0 is returned if op:duration-equal($value1, $value2) returns true.

    3. 1 is returned otherwise.

  9. If both $value1 and $value2 are instances of xs:yearMonthDuration, then:

    1. -1 is returned if op:yearMonthDuration-less-than($value1, $value2) returns true.

    2. 0 is returned if op:duration-equal($value1, $value2) returns true.

    3. 1 is returned otherwise.

  10. For any other combination of types, a type error [err:XPTY0004]XP is raised.

Notes

For numeric values, consider the xs:double value written as 0.1e0 and the xs:decimal value written as 0.1: The mathematical magnitude of this xs:double value is 0.1000000000000000055511151231257827021181583404541015625. Therefore, compare(0.1e0, 0.1) returns +1. By contrast, 0.1e0 lt 0.1 is false and 0.1e0 eq 0.1 is true, because those expressions convert the xs:decimal value 0.1 to the xs:double value 0.1e0 before the comparison.

Although operations such as sorting and the fn:min and fn:max functions invoke fn:compare to perform numeric comparison, these functions in some cases treat NaN differently.

Examples
Expression:

compare('abc', 'abc')

Result:
0
Expression:

compare('Strasse', 'Straße')

Result:
-1
Expression:

compare('Strasse', 'Straße')

Result:
0

(Assuming the default collation equates “ss” and the German letter “ß”.)

Expression:
compare(
  'Strasse',
  'Straße',
  collation({ 'lang': 'de', 'strength': 'primary' })
)
Result:
0

(The specified collation equates “ss” and the German letter “ß”.)

Expression:

compare('text', parse-xml('<xml>text</xml>'))

Result:
0
Expression:

compare(9, 10)

Result:
-1
Expression:

compare(123, 123.0)

Result:
0
Expression:

compare(xs:double('NaN'), xs:float('NaN'))

Result:
0
Expression:

compare(xs:double('NaN'), xs:double('-INF'))

Result:
-1
Expression:

compare(xs:double('-INF'), -23)

Result:
-1
Expression:

compare(1, 1e0)

Result:
0
Expression:

compare(1.1, 1.1e0)

Result:
-1
Expression:

compare(1.2, 1.2e0)

Result:
+1
Expression:

compare(9999, xs:double('INF'))

Result:
-1
Expression:

compare(false(), true())

Result:
-1
Expression:

compare(xs:hexBinary(''), xs:base64Binary(''))

Result:
0
Expression:

compare(xs:time('23:59:59'), xs:time('00:00:00'))

Result:
1
Expression:

compare(xs:date('2001-01-01+01:00'), xs:date('2001-01-01+00:00'))

Result:
-1

14.4 Aggregate functions

Aggregate functions take a sequence as argument and return a single value computed from values in the sequence. Except for fn:count, the sequence must consist of values of a single type or one if its subtypes, or they must be numeric. xs:untypedAtomic values are permitted in the input sequence and handled by special conversion rules. The type of the items in the sequence must also support certain operations.

FunctionMeaning
fn:countReturns the number of items in a sequence.
fn:avgReturns the average of the values in the input sequence $values, that is, the sum of the values divided by the number of values.
fn:maxReturns a value that is equal to the highest value appearing in the input sequence.
fn:minReturns a value that is equal to the lowest value appearing in the input sequence.
fn:sumReturns a value obtained by adding together the values in $values.
fn:all-equalReturns true if all items in a supplied sequence (after atomization) are equal.
fn:all-differentReturns true if no two items in a supplied sequence are equal.

14.4.2 fn:avg

Changes in 4.0  

  1. In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification was unclear whether it was permitted to add the first two integer items using integer arithmetic, rather than converting all items to doubles before performing any arithmetic. The 4.0 specification is clear that this is permitted; but since the items can be reordered before being added, this is not required.  [Issue 1682  PR 1734 27 January 2025]

Summary

Returns the average of the values in the input sequence $values, that is, the sum of the values divided by the number of values.

Signature
fn:avg(
$valuesas xs:anyAtomicType*
) as xs:anyAtomicType?
Properties

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

Rules

If $values is the empty sequence, the empty sequence is returned.

Any item in $values that is an instance of xs:untypedAtomic is cast to xs:double.

After this conversion, one of the following conditions must be true:

  1. Every item in $values is an instance of xs:yearMonthDuration.

  2. Every item in $values is an instance of xs:dayTimeDuration.

  3. Every item in $values is an instance of xs:numeric.

The function returns the average of the values as sum($values) div count($values); but the implementation may use an otherwise equivalent algorithm that avoids arithmetic overflow. Note that the fn:sum function allows the input sequence to be reordered, which may affect the result in edge cases when the sequence contains a mixture of different numeric types.

Error Conditions

A type error is raised [err:FORG0006] if the input sequence contains items of incompatible types, as described above.

Examples
Variables
let $d1 := xs:yearMonthDuration("P20Y")
let $d2 := xs:yearMonthDuration("P10M")
let $seq3 := (3, 4, 5)
ExpressionResult
avg($seq3)
4.0

(The result is of type xs:decimal.)

avg(($d1, $d2))
xs:yearMonthDuration("P10Y5M")
avg(())
()
avg((xs:float('INF'), xs:float('-INF')))
xs:float('NaN')
avg(($seq3, xs:float('NaN')))
xs:float('NaN')

fn:avg(($d1, $seq3)) raises a type error [err:FORG0006].

14.4.5 fn:sum

Changes in 4.0  

  1. In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification was unclear whether it was permitted to add the first two integer items using integer arithmetic, rather than converting all items to doubles before performing any arithmetic. The 4.0 specification is clear that this is permitted; but since the items can be reordered before being added, this is not required.  [Issue 1682  PR 1734 27 January 2025]

Summary

Returns a value obtained by adding together the values in $values.

Signature
fn:sum(
$valuesas xs:anyAtomicType*,
$zeroas xs:anyAtomicType?:= 0
) as xs:anyAtomicType?
Properties

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

Rules

The result of the function when a single argument is supplied is the result of the expression: fn:sum($arg, 0).

Any value of type xs:untypedAtomic in $values is cast to xs:double. The items in the resulting sequence may be reordered in an arbitrary order. The resulting sequence is referred to below as the converted sequence.

If the converted sequence is empty, then the function returns the value of the argument $zero, which defaults to the xs:integer value 0.

In other cases the items in the converted sequence are added pairwise according the rules of the + operator.

Specifically, the result of the function is the value of the expression:

if (empty($c)) then $zero
else if (count($c) eq 1) then $c
else head($c) + sum(tail($c))

where $c is the converted sequence.

This has the effect that a type error will occur unless one of the following conditions is satisfied:

  1. Every item in $values is an instance of xs:yearMonthDuration.

  2. Every item in $values is an instance of xs:dayTimeDuration.

  3. Every item in $values is an instance of xs:numeric.

Error Conditions

A type error is raised [err:FORG0006] if the input sequence contains items of incompatible types, as described above.

Notes

The second argument allows an appropriate value to be defined to represent the sum of an empty sequence. For example, when summing a sequence of durations it would be appropriate to return a zero-length duration of the appropriate type. This argument is necessary because a system that does dynamic typing cannot distinguish “an empty sequence of integers", for example, from “an empty sequence of durations”.

The explicit or implicit value of the $zero argument is used only when the input sequence is empty, not when a non-empty sequence sums to zero. For example, sum((-1, +1), xs:double('NaN')) returns the xs:integer value 0, not NaN.

The sum of a sequence of integers will be an integer, while the sum of a numeric sequence that includes at least one xs:double will be an xs:double.

If the converted sequence contains exactly one value then that value is returned.

If the converted sequence contains the value NaN, NaN is returned.

In edge cases the fact that the input sequence may be reordered makes the result slightly unpredictable. For example, if the input contains two xs:decimal values and an xs:float, then the decimal values might be added using decimal arithmetic, or they might both be converted to xs:float (potentially losing precision) before any arithmetic is performed.

Examples
Variables
let $d1 := xs:yearMonthDuration("P20Y")
let $d2 := xs:yearMonthDuration("P10M")
let $seq1 := ($d1, $d2)
let $seq3 := (3, 4, 5)
Expression:

sum(($d1, $d2))

Result:
xs:yearMonthDuration("P20Y10M")
Expression:
sum(
  $seq1[. lt xs:yearMonthDuration('P3M')],
  xs:yearMonthDuration('P0M')
)
Result:
xs:yearMonthDuration("P0M")
Expression:

sum($seq3)

Result:
12
Expression:

sum(())

Result:
0
Expression:

sum((),())

Result:
()
Expression:

sum((1 to 100)[. lt 0], 0)

Result:
0
Expression:

sum(($d1, $d2), "ein Augenblick")

Result:
xs:yearMonthDuration("P20Y10M")

(There is no requirement that the $zero value should be the same type as the items in $value, or even that it should belong to a type that supports addition.)

Expression:

sum([ 1, 2, 3 ])

Result:
6

(Atomizing an array returns the sequence obtained by atomizing its members.)

Expression:

sum([ [ 1, 2 ], [ 3, 4 ] ])

Result:
10

(Atomizing an array returns the sequence obtained by atomizing its members.)

fn:sum(($d1, 9E1)) raises a type error [err:FORG0006].

15 Parsing and serializing

These functions convert between the lexical representation and XPath and XQuery data model representation of various file formats.

15.1 Functions on XML Data

These functions convert between the lexical representation of XML and the tree representation.

(The fn:serialize function also handles HTML and JSON output, but is included in this section for editorial convenience.)

FunctionMeaning
fn:parse-xmlThis function takes as input an XML document represented as a string, and returns the document node at the root of an XDM tree representing the parsed document.
fn:parse-xml-fragmentThis function takes as input an XML external entity represented as a string, and returns the document node at the root of an XDM tree representing the parsed document fragment.
fn:serializeThis function serializes the supplied input sequence $input as described in [XSLT and XQuery Serialization 3.1], returning the serialized representation of the sequence as a string.

15.1.1 fn:parse-xml

Changes in 4.0  

  1. The $options parameter has been added.  [Issue 305 PR 1257 11 June 2024]

  2. Additional error conditions have been defined.  [Issue 1287 PR 1288 25 June 2024]

  3. Additional options to control DTD and XInclude processing have been added.  [Issues 1857 1860 PR 1879 18 March 2025]

Summary

This function takes as input an XML document represented as a string, and returns the document node at the root of an XDM tree representing the parsed document.

Signature
fn:parse-xml(
$valueas xs:string?,
$optionsas map(*)?:= {}
) as document-node(*)?
Properties

This function is nondeterministic, context-dependent, and focus-independent. It depends on static base URI.

Rules

If $value is the empty sequence, the function returns the empty sequence.

Because the input is supplied as a string, not as an octet stream, the encoding specified in the XML declaration (if present) should be ignored. For similar reasons, any initial byte order mark (codepoint U+FEFF) should be ignored.

The $options argument, if present and non-empty, defines the detailed behavior of the function. The option parameter conventions apply. The options available are as follows:

record(
base-uri?as xs:anyURI,
dtd-validation?as xs:boolean,
allow-external-entities?as xs:boolean,
entity-expansion-limit?as xs:integer?,
strip-space?as xs:boolean,
xinclude?as xs:boolean,
xsd-validation?as xs:string
)
KeyValueMeaning

base-uri?

Determines the base URI. This is used both as the base URI used by the XML parser to resolve relative entity references within the document, and as the base URI of the document node that is returned. It defaults to the static base URI of the function call.
  • Type: xs:anyURI

  • Default: static-base-uri()

dtd-validation?

Determines whether DTD validation takes place.
  • Type: xs:boolean

  • Default: false()

trueThe input is parsed using a validating XML parser. The input must contain a DOCTYPE declaration to identify the DTD to be used for validation. The DTD may be internal or external.
falseDTD validation does not take place. However, if a DOCTYPE declaration is present, then it is read, for example to perform entity expansion.

allow-external-entities?

Determines whether references to external entities (including a DTD entity) are permitted.
  • Type: xs:boolean

  • Default: true()

trueReferences to external entities are permitted, and are resolved relative to the base URI.
falseReferences to external entities (including an external DTD) are not permitted, and result in the call on parse-xml failing with a dynamic error if present.

entity-expansion-limit?

Places a limit on the maximum number of entity references that may be expanded, or on the size of the expanded entities. The limit applies both to internal and external entities, but not to built-in entity references, nor to character references.
  • Type: xs:integer?

  • Default: ()

()The limit (if any) is implementation-dependent.
integerThe processor should impose a limit on the number of entity references that are expanded, or on the size of the expanded entities, depending on the options available in the underlying XML parser; the limit should be commensurate with the value requested, but the precise effect may be . implementation-dependent. If the XML parser does not offer the ability to impose a limit, or if the value is zero, then entity expansion should if possible be disabled entirely, leading to a dynamic error if the input contains any entity references. A negative value should be interpreted as placing no limits on entity expansion.

strip-space?

Determines whether whitespace-only text nodes are removed from the resulting document. (Note: in XSLT, the xsl:strip-space and xsl:preserve-space declarations are ignored.)
  • Type: xs:boolean

  • Default: false()

trueAll whitespace-only text nodes are stripped, unless either (a) they are within the scope of the attribute xml:space="preserve", or (b) XSD validation identifies that the parent element has a simple type or a complex type with simple content.
falseAll whitespace-only text nodes are preserved, unless either (a) DTD validation marks them as ignorable, or (b) XSD validation recognizes the containing element as having element-only or empty content.

xinclude?

Determines whether any xi:include elements in the input are to be processed using an XInclude processor.
  • Type: xs:boolean

  • Default: false()

trueAny xi:include elements are expanded. If there are xi:include elements and no XInclude processor is available then a dynamic error is raised.
falseAny xi:include elements are handled as ordinary elements without expansion.

xsd-validation?

Determines whether XSD validation takes place.
  • Type: xs:string

  • Default: "skip"

strictStrict XSD validation takes place
laxLax XSD validation takes place
skipNo XSD validation takes place
type Q{uri}localXSD validation takes place against the schema-defined type, present in the static context, that has the given URI and local name.

Except to the extent defined by these options, the precise process used to construct the XDM instance is implementation-defined. In particular, it is implementation-defined whether an XML 1.0 or XML 1.1 parser is used.

The document URI of the returned node is absentDM.

The function is notdeterministic: that is, if the function is called twice with the same arguments, it is implementation-dependent whether the same node is returned on both occasions.

Options set in $options may be supplemented or modified based on configuration options defined externally using implementation-defined mechanisms.

Error Conditions

A dynamic error is raised [err:FODC0006] if the content of $value is not a well-formed and namespace-well-formed XML document.

A dynamic error is raised [err:FODC0007] if DTD validation is carried out and the content of $value is not valid against the relevant DTD.

A dynamic error is raised [err:FODC0008] if the value of the xsd-validation option is not one of the permitted values (for example, if the string that follows "type" is not a valid EQName, or if it does not identify a type that is present in the static context).

A dynamic error is raised [err:FODC0009] if the value of the xsd-validation option is set to anything other than skip when the processor is not schema-aware. (XSLT 4.0 and XQuery 4.0 define schema-awareness as an optional feature; other host languages may set their own rules.)

A dynamic error is raised [err:FODC0013] if processor does not have access to an XML parser supporting the requested options, for example the ability to perform DTD validation or XInclude processing or to prevent access to external entities.

A dynamic error is raised [err:FODC0014] if XSD validation is carried out and the content of $value is not valid against the relevant XSD schema.

Notes

Since the XML document is presented to the parser as a string, rather than as a sequence of octets, the encoding specified within the XML declaration has no meaning. If the XML parser accepts input only in the form of a sequence of octets, then the processor must ensure that the string is encoded as octets in a way that is consistent with rules used by the XML parser to detect the encoding.

A common use case for this function is to handle input documents that contain nested XML documents embedded within CDATA sections. Since the content of the CDATA section are exposed as text, the receiving query or stylesheet may pass this text to the fn:parse-xml function to create a tree representation of the nested document.

Similarly, nested XML within comments is sometimes encountered, and lexical XML is sometimes returned by extension functions, for example, functions that access web services or read from databases.

A use case arises in XSLT where there is a need to preprocess an input document before parsing. For example, an application might wish to edit the document to remove its DOCTYPE declaration. This can be done by reading the raw text using the fn:unparsed-text function, editing the resulting string, and then passing it to the fn:parse-xml function.

Examples

The expression fn:parse-xml("<alpha>abcd</alpha>") returns a newly created document node, having an alpha element as its only child; the alpha element in turn is the parent of a text node whose string value is "abcd".

The expression fn:parse-xml("<alpha><beta> </beta></alpha>", { "strip-space": true() }) returns a newly created document node, having an alpha element as its only child; the alpha element in turn is the parent of a beta element whose content is empty, as a result of whitespace stripping.

15.3 Functions on JSON Data

The functions listed in this section parse or serialize JSON data.

JSON is a popular format for exchange of structured data on the web: it is specified in [RFC 7159]. This section describes facilities allowing JSON data to be converted to and from XDM values.

This specification describes two ways of representing JSON data losslessly using XDM constructs. The first method uses XDM maps to represent JSON objects, and XDM arrays to represent JSON arrays. The second method represents all JSON constructs using XDM element and attribute nodes.

FunctionMeaning
fn:parse-jsonParses a string supplied in the form of a JSON text, returning the results typically in the form of a map or array.
fn:json-docReads an external resource containing JSON, and returns the result of parsing the resource as JSON.
fn:json-to-xmlParses a string supplied in the form of a JSON text, returning the results in the form of an XML document node.
fn:xml-to-jsonConverts an XML tree, whose format corresponds to the XML representation of JSON defined in this specification, into a string conforming to the JSON grammar.
fn:pinAdapts a map or array so that retrieval operations retain additional information.
fn:labelReturns the label associated with a labeled item, as a map.

Note also:

  • The function fn:serialize has an option to generate JSON output from a structure of maps and arrays.

  • The function fn:elements-to-maps enables arbitrary XML node trees to be converted to trees of maps and arrays suitable for serializing as JSON.

15.3.4 fn:parse-json

Changes in 4.0  

  1. The rules regarding use of non-XML characters in JSON texts have been relaxed.  [Issue 414 PR 546 25 July 2023]

  2. An option is provided to control how the JSON null value should be handled.  [Issue 960 PR 1028 20 February 2024]

  3. An option is provided to control how JSON numbers should be formatted.  [Issues 973 1037 PRs 975 1058 1246 12 March 2024]

  4. The default for the escape option has been changed to false. The 3.1 specification gave the default value as true, but this appears to have been an error, since it was inconsistent with examples given in the specification and with tests in the test suite.  [Issue 1555  PR 1565 11 November 2024]

  5. The order of entries in maps is retained.  [Issue 1651 PR 1703 14 January 2025]

Summary

Parses a string supplied in the form of a JSON text, returning the results typically in the form of a map or array.

Signature
fn:parse-json(
$valueas xs:string?,
$optionsas map(*)?:= {}
) as item()?
Properties

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

Rules

If the second argument is omitted or an empty sequence, the result is the same as calling the two-argument form with an empty map as the value of the $options argument.

The first argument is a JSON text as defined in [RFC 7159], in the form of a string. The function parses this string to return an XDM value.

If $value is the empty sequence, the function returns the empty sequence.

Note:

The result will also be an empty sequence if $value is the string "null".

The $options argument can be used to control the way in which the parsing takes place. The option parameter conventions apply.

The entries that may appear in the $options map are as follows:

record(
liberal?as xs:boolean,
duplicates?as xs:string,
escape?as xs:boolean,
fallback?as (fn(xs:string) as xs:anyAtomicType)?,
null?as item()*,
number-parser?as (fn(xs:untypedAtomic) as item()?)?
)
KeyValueMeaning

liberal?

Determines whether deviations from the syntax of RFC7159 are permitted.
  • Type: xs:boolean

  • Default: false()

false The input must consist of an optional byte order mark (which is ignored) followed by a string that conforms to the grammar of JSON-text in [RFC 7159]. An error must be raised [err:FOJS0001] if the input does not conform to the grammar.
true The input may contain deviations from the grammar of [RFC 7159], which are handled in an implementation-defined way. (Note: some popular extensions include allowing quotes on keys to be omitted, allowing a comma to appear after the last item in an array, allowing leading zeroes in numbers, and allowing control characters such as tab and newline to be present in unescaped form.) Since the extensions accepted are implementation-defined, an error may be raised [err:FOJS0001] if the input does not conform to the grammar.

duplicates?

Determines the policy for handling duplicate keys in a JSON object. To determine whether keys are duplicates, they are compared using the Unicode codepoint collation, after expanding escape sequences, unless the escape option is set to true, in which case keys are compared in escaped form.
  • Type: xs:string

  • Default: use-first

reject An error is raised [err:FOJS0003] if duplicate keys are encountered.
use-first If duplicate keys are present in a JSON object, all but the first of a set of duplicates are ignored.
use-last If duplicate keys are present in a JSON object, all but the last of a set of duplicates are ignored.

escape?

Determines whether special characters are represented in the XDM output in backslash-escaped form.
  • Type: xs:boolean

  • Default: false()

false Any permitted character in the input, whether or not it is represented in the input by means of an escape sequence, is represented as an unescaped character in the result. Any other character or codepoint (for example, an unpaired surrogate) is passed to the fallback function as described below; in the absence of a fallback function, it is replaced by U+FFFD (REPLACEMENT CHARACTER, ) .
true JSON escape sequences are used in the result to represent special characters in the JSON input, as defined below, whether or not they were represented using JSON escape sequences in the input. The characters that are considered “special” for this purpose are:
  • all codepoints in the range U+0000 (NULL) to U+001F (IS1) or U+007F (DELETE) to U+009F (APC) ;

  • all codepoints that do not represent permitted characters, including codepoints representing unpaired surrogates;

  • the character U+005C (REVERSE SOLIDUS, BACKSLASH, \) itself.

Such characters are represented using a two-character escape sequence where available (for example, \t), or a six-character escape sequence otherwise (for example \uDEAD). Characters other than these are not escaped in the result, even if they were escaped in the input.

fallback?

Provides a function which is called when the input contains an escape sequence that represents a character that is not a permitted character. It is an error to supply the fallback option if the escape option is present with the value true.
  • Type: (fn(xs:string) as xs:anyAtomicType)?

  • Default: fn { char(0xFFFD) }

User-supplied function The function is called when the JSON input contains character that is not a permitted character It is called once for any surrogate that is not properly paired with another surrogate. The untyped atomic item supplied as the argument will always be a two- or six-character escape sequence, starting with a backslash, that conforms to the rules in the JSON grammar (as extended by the implementation if liberal:true() is specified): for example \b or \uFFFF or \uDEAD.

By default, the escape sequence is replaced with the Unicode REPLACEMENT CHARACTER. The function is not called for an escape sequence that is invalid against the grammar (for example \x0A). The string, which results from invoking fn:string on the result of the function, is inserted into the result in place of the invalid character. The function also has the option of raising a dynamic error by calling fn:error.

null?

Determines how the JSON null value should be represented.
  • Type: item()*

  • Default: ()

Value The supplied XDM value is used to represent the JSON null value. The default representation of null is an empty sequence, which works well in cases where setting a property of an object to null has the same meaning as omitting the property. It works less well in cases where null is used with some other meaning, because expressions such as the lookup operators ? and ?? flatten the result to a single sequence of items, which means that any entries whose value is an empty sequence effectively disappear. The property can be set to any XDM value; a suggested value is the xs:QName value fn:QName("http://www.w3.org/2005/xpath-functions", "null"), which is recognized by the JSON serialization method as representing the JSON value null.

number-parser?

Determines how numeric values should be processed.
  • Type: (fn(xs:untypedAtomic) as item()?)?

  • Default: xs:double#1

User-supplied function The supplied function is called to process the string value of any JSON number in the input. By default, numbers are processed by converting to xs:double using the XPath casting rules. Supplying the value xs:decimal#1 will instead convert to xs:decimal (which potentially retains more precision, but disallows exponential notation), while supplying a function that casts to (xs:decimal | xs:double) will treat the value as xs:decimal if there is no exponent, or as xs:double otherwise. Supplying the value fn:identity#1 causes the value to be retained unchanged as an xs:untypedAtomic. If the liberal option is false (the default), then the supplied number-parser is called if and only if the value conforms to the JSON grammar for numbers (for example, a leading plus sign and redundant leading zeroes are not allowed). If the liberal option is true then it is also called if the value conforms to an implementation-defined extension of this grammar.

The various structures that can occur in JSON are transformed recursively to XDM values as follows:

  1. A JSON object is converted to a map. The entries in the map correspond to the key/value pairs in the JSON object. The key is always of type xs:string; the associated value may be of any type, and is the result of converting the JSON value by recursive application of these rules. For example, the JSON text { "x": 2, "y": 5 } is transformed to the value { "x": 2, "y": 5 }.

    If duplicate keys are encountered in a JSON object, they are handled as determined by the duplicates option defined above.

    The order of entries is retained.

  2. A JSON array is transformed to an array whose members are the result of converting the corresponding member of the array by recursive application of these rules. For example, the JSON text [ "a", "b", null ] is transformed (by default) to the value [ "a", "b", () ].

  3. A JSON string is converted to an xs:string value. The handling of special characters depends on the escape and fallback options, as described in the table above.

  4. A JSON number is processed using the function supplied in the number-parser option; by default it is converted to an xs:double value using the rules for casting from xs:string to xs:double.

  5. The JSON boolean values true and false are converted to the corresponding xs:boolean values.

  6. The JSON value null is converted to the value given by the null option, which defaults to an empty sequence.

Error Conditions

A dynamic error [err:FOJS0001] occurs if the value of $value does not conform to the JSON grammar, unless the option "liberal":true() is present and the processor chooses to accept the deviation.

A dynamic error [err:FOJS0003] occurs if the option "duplicates": "reject" is present and the value of $value contains a JSON object with duplicate keys.

A dynamic error [err:FOJS0005] occurs if the $options map contains an entry whose key is defined in this specification and whose value is not valid for that key, or if it contains an entry with the key fallback when the option "escape":true() is also present.

Notes

The result of the function will be an instance of one of the following types. An instance of test (or in XQuery, typeswitch) can be used to distinguish them:

  • map(xs:string, item()?) for a JSON object

  • array(item()?) for a JSON array

  • xs:string for a JSON string

  • xs:double for a JSON number

  • xs:boolean for a JSON boolean

  • empty-sequence() for a JSON null (or for empty input)

If the input starts with a byte order mark, this function ignores it. The byte order mark may have been added to the data stream in order to facilitate decoding of an octet stream to a character string, but since this function takes a character string as input, the byte order mark serves no useful purpose.

The possibility of the input containing characters that are not valid in XML (for example, unpaired surrogates) arises only when such characters are expressed using JSON escape sequences. This is because the input to the function is an instance of xs:string, which by definition (see Section 4.1.5 XML and XSD VersionsDM) cannot contain unpaired surrogates.

The serializer provides an option to output data in json-lines format. This is a format for structured data containing one JSON value (usually but not necessarily a JSON object) on each line. There is no corresponding option to parse json-lines input, but this can be achieved using the expression unparsed-text-lines($uri) => parse-json().

Examples
Expression:

parse-json('{ "x": 1, "y": [ 3, 4, 5 ] }')

Result:
{ "x": 1e0, "y": [ 3e0, 4e0, 5e0 ] }
Expression:

parse-json('"abcd"')

Result:
"abcd"
Expression:

parse-json('{ "x": "\\", "y": "\u0025" }')

Result:
{ "x": "\", "y": "%" }
Expression:
parse-json(
  '{ "x": "\\", "y": "\u0025" }',
  { 'escape': true() }
)
Result:
{ "x": "\\", "y": "%" }
Expression:
parse-json(
  '{ "x": "\\", "y": "\u0000" }'
)
Result:
{ "x": "\", "y": char(0xFFFD) }
Expression:
parse-json(
  '{ "x": "\\", "y": "\u0000" }',
  { 'escape': true() }
)
Result:
{ "x": "\\", "y": "\u0000" }
Expression:
parse-json(
  '{ "x": "\\", "y": "\u0000" }',
  { 'fallback': fn($s) { '[' || $s || ']' } }
)
Result:
{ "x": "\", "y": "[\u0000]" }
Expression:
parse-json(
  "1984.2",
  { 'number-parser': fn { xs:integer(round(.)) } }
)
Result:
1984
Expression:
parse-json(
  '[ 1, -1, 2 ]',
  { 'number-parser': fn  { boolean(. >= 0) } }
)
Result:
[ true(), false(), true() ]
Expression:
parse-json('[ "a", null, "b" ]',
  { 'null': xs:QName("fn:null") }
)
Result:
[ "a", xs:QName("fn:null"), "b" ]

17 Higher-order functions

17.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 sequence of successive partial results from the evaluation of fn:fold-left with the same arguments.
fn:scan-rightProduces the sequence of successive partial results from the evaluation of fn: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.

17.2.13 fn:partial-apply

Changes in 4.0  

  1. New in 4.0  [Issue 1816 PR 1825 25 February 2025]

Summary

Performs partial application of a function item by binding values to selected arguments.

Signature
fn:partial-apply(
$functionas fn(*),
$argumentsas map(xs:positiveInteger, item()*)
) as fn(*)
Properties

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

Rules

The result is a function obtained by binding values to selected arguments of the function item $function. The arguments to be bound are represented by entries in the $arguments map: an entry with key $i and value $v causes the argument at position $i (1-based) to be bound to $v.

Any entries in $arguments whose keys are greater than the arity of $function are ignored.

If $arguments is an empty map then the function returns $function unchanged.

For example, the effect of calling fn:partial-apply($f, { 2: $x }) is the same as the effect of the partial appplication $f(?, $x, ?, ?, ....). The coercion rules are applied to the supplied arguments in the usual way.

Unlike a partial application using place-holder arguments:

  • The arity of $function need not be statically known.

  • It is possible to bind all the arguments of $function: the effect is to return a zero-arity function.

The result is a partially applied functionXP having the following properties (which are defined in Section 7.1 Function ItemsDM):

  • name: absent.

  • identity: A new function identity distinct from the identity of any other function item.

  • arity: The arity of $function minus the number of parameters in $function that map to supplied arguments in $arguments.

  • parameter names: The names of the parameters of $function that do not map to supplied arguments in $arguments.

  • signature: The parameters in the returned function are the parameters of $function that do not map to supplied arguments in $arguments, retaining order. The result type of the returned function is the same as the result type of $function.

    An implementation that can determine a more specific signature (for example, through use of type analysis) is permitted to do so.

  • body: The body of $function.

  • captured context: The static and dynamic context of $function, augmented, for each supplied argument, with a binding of the converted argument value to the corresponding parameter name.

Error Conditions

A type error is raised if any of the supplied arguments, after applying the coercion rules, does not match the required type of the corresponding function parameter.

In addition, a dynamic error may be raised if any of the supplied arguments does not match other constraints on the value of that argument (for example, if the value supplied for a parameter expecting a regular expression is not a valid regular expression); or if the processor is able to establish that evaluation of the resulting function will fail for any other reason (for example, if an error is raised while evaluating a subexpression in the function body that depends only on explicitly supplied and defaulted parameters).

Notes

See also Section 4.5.4 Partial Function ApplicationXP.

The function is useful where the arity of a function item is not known statically, or where all arguments in a function are to be bound, returning a zero-arity function.

Examples
Expression:
let $f := partial-apply(dateTime#2,  {2: xs:time('00:00:00') })
return $f(xs:date('2025-03-01'))
Result:
xs:dateTime('2025-03-01T00:00:00')

18 Processing maps

Maps were introduced as a new datatype in XDM 3.1. This section describes functions that operate on maps.

A map is a kind of item.

[Definition] A map consists of a sequence of entries, also known as key-value pairs. Each entry comprises a key which is an arbitrary atomic item, and an arbitrary sequence called the associated value.

[Definition] Within a map, no two entries have the same key. Two atomic items K1 and K2 are the same key for this purpose if the function call fn:atomic-equal($K1, $K2) returns true.

It is not necessary that all the keys in a map should be of the same type (for example, they can include a mixture of integers and strings).

Maps are immutable, and have no identity separate from their content. For example, the map:remove function returns a map that differs from the supplied map by the omission (typically) of one entry, but the supplied map is not changed by the operation. Two calls on map:remove with the same arguments return maps that are indistinguishable from each other; there is no way of asking whether these are “the same map”.

A map can also be viewed as a function from keys to associated values. To achieve this, a map is also a function item. The function corresponding to the map has the signature function($key as xs:anyAtomicValue) as item()*. Calling the function has the same effect as calling the map:get function: the expression $map($key) returns the same result as get($map, $key). For example, if $books-by-isbn is a map whose keys are ISBNs and whose assocated values are book elements, then the expression $books-by-isbn("0470192747") returns the book element with the given ISBN. The fact that a map is a function item allows it to be passed as an argument to higher-order functions that expect a function item as one of their arguments.

18.4 Functions that Operate on Maps

The functions defined in this section use a conventional namespace prefix map, which is assumed to be bound to the namespace URI http://www.w3.org/2005/xpath-functions/map.

The function call map:get($map, $key) can be used to retrieve the value associated with a given key.

There is no operation to atomize a map or convert it to a string. The function fn:serialize can in some cases be used to produce a JSON representation of a map.

FunctionMeaning
map:buildReturns a map that typically contains one entry for each item in a supplied input sequence.
map:containsTests whether a supplied map contains an entry for a given key.
map:emptyReturns true if the supplied map contains no entries.
map:entriesReturns a sequence containing all the key-value pairs present in a map, each represented as a single-entry map.
map:entryReturns a single-entry map that represents a single key-value pair.
map:filterSelects entries from a map, returning a new map.
map:findSearches the supplied input sequence and any contained maps and arrays for a map entry with the supplied key, and returns the corresponding values.
map:for-eachApplies a supplied function to every entry in a map, returning the sequence concatenationXP of the results.
map:getReturns the value associated with a supplied key in a given map.
map:itemsReturns a sequence containing all the values present in a map, in order.
map:keysReturns a sequence containing all the keys present in a map.
map:keys-whereReturns a sequence containing selected keys present in a map.
map:mergeReturns a map that combines the entries from a number of existing maps.
map:of-pairsReturns a map that combines data from a sequence of key-value pair maps.
map:pairReturns a key-value pair map that represents a single key-value pair.
map:pairsReturns a sequence containing all the key-value pairs present in a map, each represented as a key-value pair map.
map:putReturns a map containing all the contents of the supplied map, but with an additional entry, which replaces any existing entry for the same key.
map:removeReturns a map containing all the entries from a supplied map, except those having a specified key.
map:sizeReturns the number of entries in the supplied map.

18.4.17 map:put

Changes in 4.0  

  1. Enhanced to allow for ordered maps.  [Issue 1651 PR 1703 14 January 2025]

  2. It is no longer guaranteed that the new key replaces the existing key.  [Issue 1725 PRs 1727 1740 28 January 2025]

Summary

Returns a map containing all the contents of the supplied map, but with an additional entry, which replaces any existing entry for the same key.

Signature
map:put(
$mapas map(*),
$keyas xs:anyAtomicType,
$valueas item()*
) as map(*)
Properties

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

Rules

If $map contains an entry whose key is the same key as $key, the function returns a map in which that entry is replaced (at the same relative position) with a new entry whose value is $value. It is implementation-dependent whether the key in the new entry takes its original value or is replaced by the supplied $key. All other entries in the map are unchanged, and retain their relative order.

Otherwise, when $map contains no such entry, the function returns a map containing all entries from the supplied $map (retaining their relative position) followed by a new entry whose key is $key and whose associated value is $value.

Formal Equivalent

The function is defined as follows, making use of primitive constructors and accessors defined in [XQuery and XPath Data Model (XDM) 4.0].

dm:map-put($map, $key, $value)
Notes

There is no requirement that the type of $key and $value be consistent with the types of any existing keys and values in the supplied map.

It is possible to force the new entry to go at the end of the sequence by calling map:remove before calling map:put.

It can happen that the supplied $key is the same key as some existing key present in $map, but nevertheless differs from the existing key in some way: for example, it might have a different type annotation, or it might be an xs:dateTime value in a different timezone. In this situation it is implementation-dependent whether the key that appears in the result map is the supplied $key or the existing key.

Examples
Variables
let $week := {
  0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag"
}
Expression:

map:put($week, 6, "Sonnabend")

Result:
{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Sonnabend" }
Expression:

map:put($week, -1, "Unbekannt")

Result:
{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag", -1: "Unbekannt" }
Expression:
parse-json('{ "red": 0, "green": 1, "blue": 2 }')
=> map:put("yellow", -1) 
=> map:keys()
Result:
"red", "green", "blue", "yellow"

(The new entry is added at the end of the list.)

Expression:
parse-json('{ "red": 0, "green": 1, "blue": 2 }')
=> map:put("red", -1) 
=> map:keys()
Result:
"red", "green", "blue"

(Changing the value for an existing key does not change the order of the keys.)

18.5 Converting Elements to Maps

Changes in 4.0  

  1. A new function fn:elements-to-maps is provided for converting XDM trees to maps suitable for serialization as JSON. Unlike the fn:xml-to-json function retained from 3.1, this can handle arbitrary XML as input.   [Issue 528 PR 1575 19 November 2024]

The fn:elements-to-maps function converts XML element nodes to maps, in a form suitable for serialization as JSON. This section describes the mappings used by this function.

This mapping is designed with three objectives:

  • It should be possible to represent any XML element as a map suitable for JSON serialization.

  • The resulting JSON should be intuitive and easy to use.

  • The JSON should be consistent and stable: small changes in the input should not result in large changes in the output.

Achieving all three objectives requires design compromises. It also requires sacrificing some other desiderata. In consequence:

  • The conversion is not lossless (see 18.5.5 Lost XDM Information for details).

  • The conversion is not streamable.

  • The results are not necessarily compatible with those produced by other popular libraries.

The requirement for consistency and stability is particularly challenging. An element such as <name>John</name> maps naturally to the map { "name": "John" }; but adding an attribute (so it becomes <name role="first">John</name>) then requires an incompatible change in the JSON representation. The format could be made extensible by converting <name>John</name> to { "name": {"#content":"John"} } and <name role="first">John</name> to { "name": { "@role":"first", "#content":"John" } }, but this imposes unwanted complexity on the simplest cases. The solution adopted is threefold:

  • The function makes use of schema information where available, so it considers not just the structure of an individual element instance, but the rules governing the element type.

  • It is possible to request uniform layout for all elements sharing the same name, so the decision is based on the structure of all elements with a given name, not just an individual element.

  • It is possible to override the choice made by the system, and explicitly specify a layout to be used for elements having a given name.

20 Processing types

Changes in 4.0  

  1. New functions are provided to obtain information about built-in types and types defined in an imported schema.   [Issue 148 PR 1523 5 November 2024]

The functions in this section deliver information about schema types (including simple types and complex types). These may represent built-in types (such as xs:dateTime), user-defined types found in the static context (typically because they appear in an imported schema), or types used as type annotations on schema-validated nodes.

For more information on schema types, see 1.8.2 Schema Type Hierarchy. The properties of a schema type are described in terms of the properties of a Simple Type Definition or Complex Type Definition component as described in Section 3.16.1 The Simple Type Definition Schema Component XS11-1 and Section 3.4.1 The Complex Type Definition Schema Component XS11-1 respectively. Not all properties are exposed.

The structured representation of a schema type is described in 20.1.1 Record fn:schema-type-record.

Note:

Simple properties of a schema type that can be expressed as strings or booleans are represented in this record structure directly as atomic field values, while complex properties whose values are themselves types (for example, base-type and primitive-type) are represented as functions. This is done partly to make it easier for implementations to compute complex properties on demand rather than in advance, and partly to ensure that the overall structure is always acyclic. For example, the primitive type of xs:decimal is itself xs:decimal, and if this were represented as a field value without a guarding function, serialization of the map using the JSON output method would not terminate.

G Changes since 3.1 (Non-Normative)

G.1 Summary of Changes

  1. Use the arrows to browse significant changes since the 3.1 version of this specification.

    See 1 Introduction

  2. Sections with significant changes are marked Δ in the table of contents. New functions introduced in this version are marked ➕ in the table of contents.

    See 1 Introduction

  3. PR 1620 1886 

    Options are added to customize the form of the output.

    See 2.2.6 fn:path

  4. PR 1547 1551 

    New in 4.0

    See 2.2.8 fn:siblings

  5. PR 629 803 

    New in 4.0

    See 3.2.2 fn:message

  6. PR 1260 1275 

    A third argument has been added, providing control over the rounding mode.

    See 4.4.4 fn:round

  7. New in 4.0

    See 4.4.7 fn:is-NaN

  8. PR 1049 1151 

    Decimal format parameters can now be supplied directly as a map in the third argument, rather than referencing a format defined in the static context.

    See 4.7.2 fn:format-number

  9. PR 1205 1230 

    New in 4.0

    See 4.8.2 math:e

    See 4.8.16 math:sinh

    See 4.8.17 math:cosh

    See 4.8.18 math:tanh

  10. The 3.1 specification suggested that every value in the result range should have the same chance of being chosen. This has been corrected to say that the distribution should be arithmetically uniform (because there are as many xs:double values between 0.01 and 0.1 as there are between 0.1 and 1.0).

    See 4.9.2 fn:random-number-generator

  11. PR 261 306 993 

    New in 4.0

    See 5.4.1 fn:char

  12. New in 4.0

    See 5.4.2 fn:characters

  13. PR 937 995 1190 

    New in 4.0

    See 5.4.13 fn:hash

  14. New in 4.0

    See 7.6.2 fn:parse-uri

  15. PR 1423 1413 

    New in 4.0

    See 7.6.3 fn:build-uri

  16. New in 4.0

    See 11.2.6 fn:in-scope-namespaces

  17. Reformulated in 4.0 in terms of the new fn:in-scope-namespaces function; the semantics are unchanged.

    See 11.2.7 fn:in-scope-prefixes

  18. Reformulated in 4.0 in terms of the new fn:in-scope-namespaces function; the semantics are unchanged.

    See 11.2.8 fn:namespace-uri-for-prefix

  19. New in 4.0

    See 14.1.9 fn:replicate

  20. New in 4.0

    See 14.1.12 fn:slice

  21. New in 4.0. The function is identical to the internal op:same-key function in 3.1

    See 14.2.1 fn:atomic-equal

  22. PR 1120 1150 

    A callback function can be supplied for comparing individual items.

    See 14.2.2 fn:deep-equal

  23. Changed in 4.0 to use transitive equality comparisons for numeric values.

    See 14.2.4 fn:distinct-values

  24. PR 614 987 

    New in 4.0

    See 14.2.5 fn:duplicate-values

  25. New in 4.0. Originally proposed under the name fn:uniform

    See 14.4.6 fn:all-equal

  26. New in 4.0. Originally proposed under the name fn:unique

    See 14.4.7 fn:all-different

  27. PR 1117 1279 

    The $options parameter has been added.

    See 14.6.6 fn:unparsed-text-lines

  28. Additional options to control DTD and XInclude processing have been added.

    See 15.1.1 fn:parse-xml

  29. PR 259 956 

    A new function is available for processing input data in HTML format.

    See 15.2 Functions on HTML Data

    New in 4.0

    See 15.2.2 fn:parse-html

  30. PR 975 1058 1246 

    An option is provided to control how JSON numbers should be formatted.

    See 15.3.4 fn:parse-json

  31. Additional options are available, as defined by fn:parse-json.

    See 15.3.5 fn:json-doc

  32. PR 533 719 834 1066 

    New in 4.0

    See 15.4.4 fn:csv-to-arrays

    See 15.4.7 fn:parse-csv

  33. PR 533 719 834 1066 1605 

    New in 4.0

    See 15.4.9 fn:csv-to-xml

  34. PR 791 1256 1282 1405 

    New in 4.0

    See 15.5.1 fn:invisible-xml

  35. New in 4.0

    See 17.2.4 fn:every

  36. New in 4.0

    See 17.2.10 fn:highest

  37. New in 4.0

    See 17.2.11 fn:index-where

  38. New in 4.0

    See 17.2.12 fn:lowest

  39. New in 4.0

    See 17.2.16 fn:scan-right

  40. New in 4.0

    See 17.2.17 fn:some

  41. PR 521 761 

    New in 4.0

    See 17.2.22 fn:transitive-closure

  42. New in 4.0

    See 18.4.6 map:filter

  43. New in 4.0

    See 18.4.10 map:items

  44. PR 478 515 

    New in 4.0

    See 18.4.12 map:keys-where

  45. New in 4.0

    See 18.4.14 map:of-pairs

  46. New in 4.0

    See 18.4.15 map:pair

  47. New in 4.0

    See 18.4.16 map:pairs

  48. New in 4.0.

    See 18.5.7 fn:elements-to-maps

  49. New in 4.0

    See 19.2.3 array:empty

  50. PR 968 1295 

    New in 4.0

    See 19.2.13 array:index-of

  51. PR 476 1087 

    New in 4.0

    See 19.2.16 array:items

  52. PR 360 476 

    New in 4.0

    See 19.2.18 array:members

    See 19.2.19 array:of-members

  53. New in 4.0

    See 19.2.24 array:slice

  54. New in 4.0

    See 19.2.25 array:sort

  55. New in 4.0

    See 19.2.26 array:split

  56. Supplying an empty sequence as the value of an optional argument is equivalent to omitting the argument.

    See 19.2.27 array:subarray

  57. New functions are provided to obtain information about built-in types and types defined in an imported schema.

    See 20 Processing types

  58. PR 533 719 834 

    New functions are available for processing input data in CSV (comma separated values) format.

    See 15.4 Functions on CSV Data

  59. PR 734 1233 

    New in 4.0

    See 17.2.2 fn:chain

  60. A new function fn:elements-to-maps is provided for converting XDM trees to maps suitable for serialization as JSON. Unlike the fn:xml-to-json function retained from 3.1, this can handle arbitrary XML as input.

    See 18.5 Converting Elements to Maps

  61. New in 4.0

    See 14.1.5 fn:identity

  62. New in 4.0.

    See 4.4.6 fn:divide-decimals

  63. PR 289 1901 

    A third argument is added, allowing user control of how absent keys should be handled.

    See 18.4.9 map:get

    A third argument is added, allowing user control of how index-out-of-bounds conditions should be handled.

    See 19.2.11 array:get

  64. The default for the escape option has been changed to false. The 3.1 specification gave the default value as true, but this appears to have been an error, since it was inconsistent with examples given in the specification and with tests in the test suite.

    See 15.3.4 fn:parse-json

  65. The spec has been corrected to note that the function depends on the implicit timezone.

    See 14.2.3 fn:compare

  66. In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification was unclear whether it was permitted to add the first two integer items using integer arithmetic, rather than converting all items to doubles before performing any arithmetic. The 4.0 specification is clear that this is permitted; but since the items can be reordered before being added, this is not required.

    See 14.4.2 fn:avg

    See 14.4.5 fn:sum

  67. It is explicitly stated that the limits for $precision are implementation-defined.

    See 4.4.4 fn:round

    See 4.4.5 fn:round-half-to-even

  68. PR 1727 1740 

    It is no longer guaranteed that the new key replaces the existing key.

    See 18.4.17 map:put

  69. New in 4.0

    See 17.2.13 fn:partial-apply

  70. The $replacement argument can now be a function that computes the replacement strings.

    See 6.3.2 fn:replace

  71. PR 173 

    New in 4.0

    See 17.3.4 fn:op

  72. PR 203 

    New in 4.0

    See 18.4.1 map:build

  73. PR 207 

    New in 4.0

    See 11.1.2 fn:parse-QName

    See 11.2.5 fn:expanded-QName

  74. PR 222 

    New in 4.0

    See 14.2.7 fn:starts-with-subsequence

    See 14.2.8 fn:ends-with-subsequence

    See 14.2.9 fn:contains-subsequence

  75. PR 250 

    New in 4.0

    See 14.1.3 fn:foot

    See 14.1.15 fn:trunk

    See 19.2.2 array:build

    See 19.2.8 array:foot

    See 19.2.29 array:trunk

  76. PR 258 

    New in 4.0

    See 19.2.14 array:index-where

  77. PR 313 

    The second argument can now be a sequence of integers.

    See 14.1.8 fn:remove

  78. PR 314 

    New in 4.0

    See 18.4.4 map:entries

  79. PR 326 

    Higher-order functions are no longer an optional feature.

    See 1.2 Conformance

  80. PR 419 

    New in 4.0

    See 14.1.7 fn:items-at

  81. PR 434 

    New in 4.0

    See 4.5.2 fn:parse-integer

    The function has been extended to allow output in a radix other than 10, for example in hexadecimal.

    See 4.6.1 fn:format-integer

  82. PR 482 

    Deleted an inaccurate statement concerning the behavior of NaN.

    See 4.3 Comparison operators on numeric values

  83. PR 507 

    New in 4.0

    See 17.2.14 fn:partition

  84. PR 546 

    The rules regarding use of non-XML characters in JSON texts have been relaxed.

    See 15.3.3 JSON character repertoire

    See 15.3.4 fn:parse-json

  85. PR 623 

    Substantially revised to allow multiple sort key definitions.

    See 17.2.18 fn:sort

  86. PR 631 

    New in 4.0

    See 7.3 fn:decode-from-uri

  87. PR 662 

    Constructor functions now have a zero-arity form; the first argument defaults to the context item.

    See 21 Constructor functions

  88. PR 680 

    The case-insensitive collation is now defined normatively within this specification, rather than by reference to the HTML "living specification", which is subject to change. The collation can now be used for ordering comparisons as well as equality comparisons.

    See 5.3.5 The HTML ASCII Case-Insensitive Collation

  89. PR 702 

    The function can now take any number of arguments (previously it had to be two or more), and the arguments can be sequences of strings rather than single strings.

    See 5.4.4 fn:concat

  90. PR 710 

    Changes the function to return a sequence of key-value pairs rather than a map.

    See 17.1.5 fn:function-annotations

  91. PR 727 

    It has been clarified that loading a module has no effect on the static or dynamic context of the caller.

    See 17.3.2 fn:load-xquery-module

  92. PR 795 

    New in 4.0

    See 17.2.19 fn:sort-with

  93. PR 828 

    The $predicate callback function accepts an optional position argument.

    See 17.2.5 fn:filter

    The $action callback function accepts an optional position argument.

    See 17.2.7 fn:fold-right

    See 17.2.8 fn:for-each

    See 17.2.9 fn:for-each-pair

    The $predicate callback function now accepts an optional position argument.

    See 19.2.4 array:filter

    The $action callback function now accepts an optional position argument.

    See 19.2.7 array:fold-right

    See 19.2.9 array:for-each

    See 19.2.10 array:for-each-pair

  94. PR 881 

    The way that fn:min and fn:max compare numeric values of different types has changed. The most noticeable effect is that when these functions are applied to a sequence of xs:integer or xs:decimal values, the result is an xs:integer or xs:decimal, rather than the result of converting this to an xs:double

    See 14.4.3 fn:max

    See 14.4.4 fn:min

  95. PR 901 

    All three arguments are now optional, and each argument can be set to an empty sequence. Previously if $description was supplied, it could not be empty.

    See 3.1.1 fn:error

    The $label argument can now be set to an empty sequence. Previously if $label was supplied, it could not be empty.

    See 3.2.1 fn:trace

    The third argument can now be supplied as an empty sequence.

    See 5.4.6 fn:substring

    The second argument can now be an empty sequence.

    See 6.3.3 fn:tokenize

    The optional second argument can now be supplied as an empty sequence.

    See 7.1 fn:resolve-uri

    The 3rd, 4th, and 5th arguments are now optional; previously the function required either 2 or 5 arguments.

    See 10.8.1 fn:format-dateTime

    See 10.8.2 fn:format-date

    See 10.8.3 fn:format-time

    The optional third argument can now be supplied as an empty sequence.

    See 14.1.13 fn:subsequence

  96. PR 905 

    The rule that multiple calls on fn:doc supplying the same absolute URI must return the same document node has been clarified; in particular the rule does not apply if the dynamic context for the two calls requires different processing of the documents (such as schema validation or whitespace stripping).

    See 14.6.1 fn:doc

  97. PR 909 

    The function has been expanded in scope to handle comparison of values other than strings.

    See 14.2.3 fn:compare

  98. PR 924 

    Rules have been added clarifying that users should not be allowed to change the schema for the fn namespace.

    See C Schemas

  99. PR 925 

    The decimal format name can now be supplied as a value of type xs:QName, as an alternative to supplying a lexical QName as an instance of xs:string.

    See 4.7.2 fn:format-number

  100. PR 932 

    The specification now prescribes a minimum precision and range for durations.

    See 9.1.2 Limits and precision

  101. PR 933 

    When comments and processing instructions are ignored, any text nodes either side of the comment or processing instruction are now merged prior to comparison.

    See 14.2.2 fn:deep-equal

  102. PR 940 

    New in 4.0

    See 17.2.20 fn:subsequence-where

  103. PR 953 

    Constructor functions for named record types have been introduced.

    See 21.6 Constructor functions for named record types

  104. PR 962 

    New in 4.0

    See 17.2.3 fn:do-until

    See 17.2.23 fn:while-do

  105. PR 969 

    New in 4.0

    See 18.4.3 map:empty

  106. PR 984 

    New in 4.0

    See 9.4.1 fn:seconds

  107. PR 987 

    The order of results is now prescribed; it was previously implementation-dependent.

    See 14.2.4 fn:distinct-values

  108. PR 988 

    New in 4.0

    See 15.3.8 fn:pin

    See 15.3.9 fn:label

  109. PR 1022 

    Regular expressions can include comments (starting and ending with #) if the c flag is set.

    See 6.1 Regular expression syntax

    See 6.2 Flags

  110. PR 1028 

    An option is provided to control how the JSON null value should be handled.

    See 15.3.4 fn:parse-json

  111. PR 1032 

    New in 4.0

    See 14.1.17 fn:void

  112. PR 1046 

    New in 4.0

    See 17.2.21 fn:take-while

  113. PR 1059 

    Use of an option keyword that is not defined in the specification and is not known to the implementation now results in a dynamic error; previously it was ignored.

    See 1.7 Options

  114. PR 1068 

    New in 4.0

    See 5.4.3 fn:graphemes

  115. PR 1072 

    The return type is now specified more precisely.

    See 17.3.2 fn:load-xquery-module

  116. PR 1090 

    When casting from a string to a duration or time or dateTime, it is now specified that when there are more digits in the fractional seconds than the implementation is able to retain, excess digits are truncated. Rounding upwards (which could affect the number of minutes or hours in the value) is not permitted.

    See 22.2 Casting from xs:string and xs:untypedAtomic

  117. PR 1093 

    New in 4.0

    See 5.3.8 fn:collation

  118. PR 1117 

    The $options parameter has been added.

    See 14.6.5 fn:unparsed-text

    See 14.6.7 fn:unparsed-text-available

  119. PR 1182 

    The $predicate callback function may return an empty sequence (meaning false).

    See 17.2.3 fn:do-until

    See 17.2.4 fn:every

    See 17.2.5 fn:filter

    See 17.2.11 fn:index-where

    See 17.2.17 fn:some

    See 17.2.21 fn:take-while

    See 17.2.23 fn:while-do

    See 18.4.6 map:filter

    See 18.4.12 map:keys-where

    See 19.2.4 array:filter

    See 19.2.14 array:index-where

  120. PR 1191 

    New in 4.0

    See 2.3.1 fn:distinct-ordered-nodes

    The $options parameter has been added, absorbing the $collation parameter.

    See 14.2.2 fn:deep-equal

  121. PR 1250 

    For selected properties including percent and exponent-separator, it is now possible to specify a single-character marker to be used in the picture string, together with a multi-character rendition to be used in the formatted output.

    See 4.7.2 fn:format-number

  122. PR 1257 

    The $options parameter has been added.

    See 15.1.1 fn:parse-xml

    See 15.1.2 fn:parse-xml-fragment

  123. PR 1262 

    New in 4.0

    See 5.3.9 fn:collation-available

  124. PR 1265 

    The constraints on the result of the function have been relaxed.

    See 2.1.6 fn:document-uri

  125. PR 1280 

    As a result of changes to the coercion rules, the number of supplied arguments can be greater than the number required: extra arguments are ignored.

    See 17.2.1 fn:apply

  126. PR 1288 

    Additional error conditions have been defined.

    See 15.1.1 fn:parse-xml

  127. PR 1296 

    New in 4.0

    See 17.2.15 fn:scan-left

  128. PR 1333 

    A new option is provided to allow the content of the loaded module to be supplied as a string.

    See 17.3.2 fn:load-xquery-module

  129. PR 1353 

    An option has been added to suppress the escaping of the solidus (forwards slash) character.

    See 15.3.7 fn:xml-to-json

  130. PR 1358 

    New in 4.0

    See 10.3.2 fn:unix-dateTime

  131. PR 1361 

    The term atomic value has been replaced by atomic item.

    See 1.9 Terminology

  132. PR 1393 

    Changes the function to return a sequence of key-value pairs rather than a map.

    See 17.1.5 fn:function-annotations

  133. PR 1409 

    This section now uses the term primitive type strictly to refer to the 20 atomic types that are not derived by restriction from another atomic type: that is, the 19 primitive atomic types defined in XSD, plus xs:untypedAtomic. The three types xs:integer, xs:dayTimeDuration, and xs:yearMonthDuration, which have custom casting rules but are not strictly-speaking primitive, are now handled in other subsections.

    See 22.1 Casting from primitive types to primitive types

    The rules for conversion of dates and times to strings are now defined entirely in terms of XSD 1.1 canonical mappings, since these deliver exactly the same result as the XPath 3.1 rules.

    See 22.1.2.2 Casting date/time values to xs:string

    The rules for conversion of durations to strings are now defined entirely in terms of XSD 1.1 canonical mappings, since the XSD 1.1 rules deliver exactly the same result as the XPath 3.1 rules.

    See 22.1.2.3 Casting xs:duration values to xs:string

  134. PR 1455 

    Numbers now retain their original lexical form, except for any changes needed to satisfy JSON syntax rules (for example, stripping leading zero digits).

    See 15.3.7 fn:xml-to-json

  135. PR 1473 

    New in 4.0

    See 14.1.5 fn:identity

  136. PR 1481 

    The function has been extended to handle other Gregorian types such as xs:gYearMonth.

    See 10.5.1 fn:year-from-dateTime

    See 10.5.2 fn:month-from-dateTime

    The function has been extended to handle other Gregorian types such as xs:gMonthDay.

    See 10.5.3 fn:day-from-dateTime

    The function has been extended to handle other types including xs:time.

    See 10.5.4 fn:hours-from-dateTime

    See 10.5.5 fn:minutes-from-dateTime

    The function has been extended to handle other types such as xs:gYearMonth.

    See 10.5.7 fn:timezone-from-dateTime

  137. PR 1504 

    New in 4.0

    See 14.1.11 fn:sequence-join

    Optional $separator added.

    See 19.2.17 array:join

  138. PR 1523 

    New in 4.0

    New functions are provided to obtain information about built-in types and types defined in an imported schema.

    See 20 Processing types

    New in 4.0

    See 20.1.2 fn:schema-type

    See 20.1.4 fn:atomic-type-annotation

    See 20.1.5 fn:node-type-annotation

  139. PR 1545 

    New in 4.0

    See 10.6.4 fn:civil-timezone

  140. PR 1565 

    The default for the escape option has been changed to false. The 3.1 specification gave the default value as true, but this appears to have been an error, since it was inconsistent with examples given in the specification and with tests in the test suite.

    See 15.3.4 fn:parse-json

  141. PR 1570 

    New in 4.0

    See 20.1.3 fn:type-of

  142. PR 1575 

    A new function fn:elements-to-maps is provided for converting XDM trees to maps suitable for serialization as JSON. Unlike the fn:xml-to-json function retained from 3.1, this can handle arbitrary XML as input.

    See 18.5 Converting Elements to Maps

  143. PR 1611 

    The spec has been corrected to note that the function depends on the implicit timezone.

    See 14.2.3 fn:compare

  144. PR 1671 

    New in 4.0.

    See 4.4.6 fn:divide-decimals

  145. PR 1703 

    The order of entries in maps is retained.

    See 15.3.4 fn:parse-json

    Ordered maps are introduced.

    See 18.1 Ordering of Maps

    Enhanced to allow for ordered maps.

    See 18.4.6 map:filter

    See 18.4.7 map:find

    See 18.4.8 map:for-each

    See 18.4.17 map:put

    See 18.4.18 map:remove

  146. PR 1711 

    It is explicitly stated that the limits for $precision are implementation-defined.

    See 4.4.4 fn:round

    See 4.4.5 fn:round-half-to-even

  147. PR 1727 

    For consistency with the new functions map:build and map:of-pairs, the handling of duplicates may now be controlled by supplying a user-defined callback function as an alternative to the fixed values for the earlier duplicates option.

    See 18.4.13 map:merge

  148. PR 1734 

    In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification was unclear whether it was permitted to add the first two integer items using integer arithmetic, rather than converting all items to doubles before performing any arithmetic. The 4.0 specification is clear that this is permitted; but since the items can be reordered before being added, this is not required.

    See 14.4.2 fn:avg

    See 14.4.5 fn:sum

  149. PR 1825 

    New in 4.0

    See 17.2.13 fn:partial-apply

  150. PR 1856 

    Word boundaries can be matched. Lookahead and lookbehind assertions are supported. Assertions (including ^ and $) can no longer be followed by a quantifier.

    See 6.1 Regular expression syntax

    It is now permitted for the regular expression to match a zero-length string.

    See 6.3.2 fn:replace

    See 6.3.3 fn:tokenize

    The output of the function is extended to allow the represention of captured groups found within lookahead assertions.

    See 6.3.4 fn:analyze-string

    It is now permitted for the regular expression to match a zero-length string.

    See 6.3.4 fn:analyze-string

  151. PR 1879 

    Additional options to control DTD and XInclude processing have been added.

    See 15.1.1 fn:parse-xml

  152. PR 1897 

    The $replacement argument can now be a function that computes the replacement strings.

    See 6.3.2 fn:replace

  153. PR 1910 

    An $options parameter is added. Note that the rules for the $options parameter control aspects of processing that were implementation-defined in earlier versions of this specification. An implementation may provide configuration options designed to retain backwards-compatible behavior when no explicit options are supplied.

    See 14.6.1 fn:doc

    See 14.6.2 fn:doc-available