This document is also available in these non-normative formats: Specification in XML format and XML function catalog.
Copyright © 2000 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
This document defines constructor functions, operators, and functions on the datatypes defined in [XML Schema Part 2: Datatypes Second Edition] and the datatypes defined in [XQuery and XPath Data Model (XDM) 4.0]. It also defines functions and operators on nodes and node sequences as defined in the [XQuery and XPath Data Model (XDM) 4.0]. 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 H Changes since 3.1.
This section describes the status of this document at the time of its publication. Other documents may supersede this document.
This document is a working draft developed and maintained by a W3C Community Group, the XQuery and XSLT Extensions Community Group unofficially known as QT4CG (where "QT" denotes Query and Transformation). This draft is work in progress and should not be considered either stable or complete. Standard W3C copyright and patent conditions apply.
The community group welcomes comments on the specification. Comments are best submitted as issues on the group's GitHub repository.
The community group maintains two extensive test suites, one oriented to XQuery and XPath, the other to XSLT. These can be found at qt4tests and xslt40-test respectively. New tests, or suggestions for correcting existing tests, are welcome. The test suites include extensive metadata describing the conditions for applicability of each test case as well as the expected results. They do not include any test drivers for executing the tests: each implementation is expected to provide its own test driver.
The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).
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].
The functions in this section perform comparisons between the items in one or more sequences.
Many of these functions require atomic items to be compared for equality.
[Definition] Two atomic items A and B are said to be contextually equal if the function call fn:compare(A, B) returns zero when evaluated with a specified or context-determined collation and implicit timezone. If two values are not contextually equal, they are considered to be contextually unequal, even in the case when comparing them using fn:compare raises an error.
Note:
Except where explicitly stated otherwise, an appeal to contextual equality implies that NaN is treated as equal to NaN.
| Function | Meaning |
|---|---|
fn:atomic-equal | Determines whether two atomic items are equal, under the rules used for comparing keys in a map. |
fn:compare | Returns -1, 0, or 1, depending on whether the first value is less than, equal to, or greater than the second value. |
fn:contains-subsequence | Determines whether one sequence contains another as a contiguous subsequence, using a supplied callback function to compare items. |
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:distinct-values | Returns the values that appear in a sequence, with duplicates eliminated. |
fn:duplicate-values | Returns the values that appear in a sequence more than once. |
fn:ends-with-subsequence | Determines whether one sequence ends with another, using a supplied callback function to compare items. |
fn:index-of | Returns a sequence of positive integers giving the positions within the sequence $input of items that are contextually equal to $target. |
fn:starts-with-subsequence | Determines whether one sequence starts with another, using a supplied callback function to compare items. |
Returns -1, 0, or 1, depending on whether the first value is less than, equal to, or greater than the second value.
fn:compare( | ||
$value1 | as , | |
$value2 | as , | |
$collation | as | := fn:default-collation() |
) as | ||
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.
The function 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 is transitive and symmetric. For example:
If compare(A, B) returns zero, then compare(B, A) returns zero.
If compare(A, B) returns -1, then compare(B, A) returns +1.
If compare(A, B) and compare(B, C) both return -1, then compare(A, C) also returns -1.
If either $value1 or $value2 is the empty sequence, the function returns the empty sequence.
Otherwise, the result is determined as follows:
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.7 Choosing a collation.
Note:
Using the default collation may be inappropriate for some strings, for example URIs or manufacturing part numbers. In such cases it is safest to supply "http://www.w3.org/2005/xpath-functions/collation/codepoint" explicitly as the third argument.
If both $value1 and $value2 are instances of xs:numeric, the function relies on a total order, which is defined as follows:
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.
NaN is equal to itself and less than any other value.
Negative infinity is equal to itself and less than any other value except NaN.
Positive infinity is equal to itself and greater than any other value.
Negative zero is equal to positive zero.
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.
Note:
Every xs:double other than NaN and ±INF, has a mathematical value of the form m × 2^e, where m is an integer whose absolute value is less than 2^53, and e is an integer between -1075 and 970, inclusive. This is the value that is used in comparisons.
Practical difficulties arise because the typical string representations of an xs:double, such as 3.1, cannot be precisely represented by values of the form m × 2^e, but are instead converted to the best available approximation, which will often not be exactly equal to an xs:decimal expressed using the same lexical form.
If both $value1 and $value2 are instances of xs:boolean, the result is fn:compare(xs:integer($value1), xs:integer($value2))
Note:
This means that false is treated as less than true.
If $value1 is an instance of xs:hexBinary or xs:base64Binary, and if $value2 is an instance of xs:hexBinary or xs:base64Binary, then:
Let $A be the sequence of integers, in the range (0 to 255), representing the octets of $value1, in order; and let $B similarly be the sequence of integers representing the octets of $value2.
If $A is empty and $B is empty return zero.
If $A is empty and $B is not empty return -1.
Let $C be the value of fn:compare(fn:head($A), fn:head($B)).
If $C is non-zero, then return $C.
Otherwise, return the result of applying these rules recursively to fn:tail($A) and fn:tail($B)
If both $value1 and $value2 are instances of the same primitive type T, where T is one of the types xs:dateTime, xs:date, xs:time, xs:gYear, xs:gYearMonth, xs:gMonth, gMonthDay, or gDay, then:
Each of the values is converted to an xs:dateTime value as follows:
The value is considered as a tuple with seven fields (year, month, day, hours, minutes, seconds, timezone) as defined by the functions fn:year-from-dateTime, fn:months-from-dateTime, and so on.
Any absent components, other than the timezone, are substituted with the corresponding components of the (arbitrary) xs:dateTime value 1972-01-01T00:00:00 to produce an xs:dateTime value.
If the timezone component is absent, it is substituted with the implicit timezone from the dynamic context.
Note:
The xs:dateTime1972-01-01T00:00:00 is arbitrary. The only constraint is that the year must be a leap year (so that the xs:gYearMonth value --02-29 expands to a valid date). XSD originally chose this as the being historically the first date on which there was a leap second, but this is irrelevant as leap seconds are not supported in XDM.
The result of the function is then the result of comparing the starting instants of these two xs:dateTime values according to the algorithm defined in section 3.2.7.4 of [XML Schema Part 2: Datatypes Second Edition] ( “Order relation on dateTime” for xs:dateTime values with timezones).
If both $value1 and $value2 are instances of xs:duration, then:
Let $M1 and $M2 be the months components of the two durations, and let $S1 and $S2 be the seconds components of the two durations.
Let $C be fn:compare($M1, $M2).
If $C is non-zero, return $C.
Otherwise, return fn:compare($S1, $S2).
Note:
The result matches the real-world semantics of durations in many cases, for example:
When both values are zero-length durations.
When both values are have an equal months component (in particular when both have a zero months component).
When both values are have an equal seconds component (in particular when both have a zero seconds component).
When both values have a seconds component that is less than the number of seconds in the shortest month.
In other cases the result is well defined and well behaved (for example it is symmetric and transitive) but may be counter-intuitive. For example, one month (PT1M) is considered greater than one hundred days (PT100D).
Previous versions of this specification allowed durations to be compared only if both were instances of xs:dateTimeDuration or xs:yearMonthDuration. This requirement has been relaxed in the interests of allowing all atomic items to be sorted; in some applications the actual sort order matters little, so long as it is consistent.
If both $value1 and $value2 are instances of xs:QName, then:
Let $N1 and $N2 be the result of applying the function fn:namespace-uri-from-QName to the two values, and let $L1 and $L2 be the result of applying the function local-name-from-QName to the two values.
Let $CPC be "http://www.w3.org/2005/xpath-functions/collation/codepoint".
Let $C be fn:compare($N1, $N2, $CPC).
If $C is non-zero, return $C.
Otherwise, return fn:compare($L1, $L2, $CPC).
If both $value1 and $value2 are instances of xs:NOTATION, return fn:compare(xs:QName($value1), xs:QName($value2)).
For any other combination of types, a type error [err:XPTY0004]XP is raised. In particular, this means that an error is raised when comparing two atomic items that belong to different [XQuery and XPath Data Model (XDM) 4.0] section .
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.
| Expression: |
|
|---|---|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
(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: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|
| Expression: |
|
| Result: |
|