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


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.2 Composing and Decomposing Maps

It is often useful to decompose a map into a sequence of entries, or key-value pairs (in which the key is an atomic item and the value is an arbitrary sequence). Subsequently it may be necessary to reconstruct a map from these components, typically after modification.

There are two conventional ways of representing a map as a sequence of key-value pairs, each with its own advantages and disadvantages. These are described below:

  1. A map can be represented as a sequence of single-entry maps.

    [Definition] A single-entry map is a map containing a single entry.

    It is possible to decompose any map into a sequence of single-entry maps, and to construct a map from a sequence of single-entry maps.

    For example the map { "x": 1, "y": 2 } can be decomposed to the sequence ({ "x": 1 }, { "y": 2 }).

  2. A map can be represented as a sequence of JNodes.

    A JNode holds the map key in its ·selector· property and the corresponding value in its ·content· property.

The following table summarizes the way in which these two representations can be used to compose and decompose maps:

OperationSingle-Entry MapsJNodes

Decompose a map

map:entries($map)

$map/child::*

Compose a map

map:merge($entries)

map:build($jnodes, jnode-selector#1, jnode-content#1)

Create a single entry

map:entry($key, $value)

{$key : $value}/child::*

Extract the key part of a single entry

map:keys($entry)

jnode-selector($jnode)

Extract the value part of a single entry

map:items($entry)

jnode-content($jnode)

It is also possible to decompose a map using:

  • The function map:for-each

  • The expression for key $k value $v in $map return ....

Example: Reordering the entries in a map

The examples below show several ways of constructing a map with the same entries as an input map, but with the entries sorted by key.

  1. Using map:entries and map:merge:

    map:entries($map) => sort-by(map:keys#1) => map:merge()
    map:entries($map) => sort-by({'key': map:keys#1}) => map:merge()
  2. Using JNodes:

    $map/* => sort-by(jnode-selector#1) => map:build(jnode-selector#1, jnode-content#1)
    $map/* => sort-by({'key': jnode-selector#1}) => map:build(jnode-selector#1, jnode-content#1)
  3. Using map:for-each:

    map:merge( map:for-each($map, map:entry#2) => sort-by(map:keys#1) )
    map:merge( map:for-each($map, map:entry#2) => sort-by({'key': map:keys#1}) )
  4. Using an XQuery FLWOR expression:

    map:merge( for key $k value $v order by $k return {$k : $v} )