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


15 Parsing and serializing

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

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:element-to-map enables arbitrary XML node trees to be converted to trees of maps and arrays suitable for serializing as JSON.

15.3.8 fn:pin

Changes in 4.0  

  1. New in 4.0  [Issue 960 PR 988 27 February 2024]

Summary

Adapts a map or array so that retrieval operations retain additional information.

Signature
fn:pin(
$inputas (map(*)|array(*))
) as (map(*)|array(*))
Properties

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

Rules

The function creates a deep copy of the supplied map or array, adapted so that navigation within the deep copy returns items that are labeled with additional information about their position within the containing tree structure.

Note:

The formal specification of the function describes it as constructing a deep copy of the entire tree, but a practical implementation is likely to use a lazy evaluation strategy, so the only costs incurred are for items actually selected within the tree.

The function makes use of the concept of labeled items, an extension to the data model described in Section 3.3 Labeled ItemsDM.

The supplied value of $input must be either a map or an array.

The result is as follows:

  1. We define an auxiliary function pin2($item, $root) which pins an item $item (of any kind) as part of a tree rooted at $root. This function is described in the following rules. The function fn:pin($input) is defined to return pin2($input, $input): that is, it processes the supplied item as the root of a tree.

  2. If $inputitem is a map M, the result of pin2($item, $root) is a map M′ derived from M as follows:

    1. Any existing label on M is discarded.

    2. M′ acquires a label having the property pinned set to the value true, and the property id set to an arbitrary xs:string value that is unique within the execution scope.

      M′ acquires a label having the following properties:

      1. Property pinned set to the value true.

      2. Property id set to an arbitrary xs:string value that is unique within the execution scope.

      3. Property root set to $root.

    3. For every key-value pair (K, V) in M, M′ will have a key-value pair (K, V′) in which the key K is unchanged, and the value V′ is derived from V by applying the function derived-value(M', K, V, $root), defined below.

    4. The entry orderDM of M is retained in M′.

  3. If $input is an array A, the result is an array A′ derived from A as follows:

    1. Any existing label on A is discarded.

    2. A′ acquires a label having the property pinned set to the value true, and the property id set to an arbitrary xs:string value that is unique within the execution scope.

      A′ acquires a label having the following properties:

      1. Property pinned set to the value true.

      2. Property id set to an arbitrary xs:string value that is unique within the execution scope.

      3. Property root set to $root.

    3. For every member V in A, whose 1-based index position in A is X, A′ will have a member V′ derived from V by applying the function derived-value(A', X, V, $root), defined below.

  4. The id property described in the previous paragraphs is allocated only to the top-level map or array (the one supplied as an explicit argument toidentifies an item uniquely within the fn:pin function)execution scope. The fn:pin function is notdeterministic: that is, if the function is called twice with the same arguments, it is implementation-dependent whether the same id property is allocated on both occasions.

  5. If $input is anything other than a map or an array, a type error is raised.

  6. The function derived-value(P, K, V, $root) has the following logic. For every item J in V, the result V′ will contain an item J′ that is derived from J as follows:

    1. Let TEMP be:

      1. If J is a map or array, then fn:pinpin2(J, $root).

        Note:

        Note however that the id property of TEMP is not used, so there is no need to generate it.

      2. Otherwise, J.

    2. J′ is then a labeled item having the same subject as TEMP, together with a label having the following properties:

      pinned

      true

      id

      A string that uniquely identifies this item within the tree rooted at $root

      key

      K

      position

      The 1-based position of J within V.

      parent

      A zero-arity function delivering P.

      root

      A zero-arity function delivering $root.

      ancestors

      A zero-arity function item delivering the value of (?parent(), ?parent() ! label(.)?ancestors()).

      path

      A zero-arity function item delivering the value of (?parent() ! label(.)?path(), ?key).

Notes

The effect of calling pin on a map or array is that subsequent retrieval operations within the pinned map or array return labeled results, whose labels contain useful information about where the results were found. For example, an expression such as json-doc($source)??name will return the values of all entries in the JSON tree having the key "name"; but very little can be done with this information because the result is simply a sequence of (typically) strings with no context. By contrast, the result of pin(json-doc($source))??name is the same set of strings, labeled with information about where they were found. For example, if $result is the result of the expression pin(json-doc($source))??name, then:

  • $result => label()?parent?ssn locates the map that contained each name, and returns the value of the ssn entry in that map.

  • $result => label()?ancestors()?course returns the values of any course entries in containing maps.

  • $result => label()?path() returns a sequence of map keys and array index values representing the location of the found entries within the JSON structure.

Editorial note 
The id property on the root of a pinned map or array is intended to support deep update operations, which have not yet been defined.
Examples
Expression:

pin([ "a", "b", "c" ])?1 ! label(.)?parent ! array:foot(.)

Result:
"c"
Expression:

pin([ "a", "b", "c", "d" ]) ! array:remove(., 2)?* ! label(.)?key

Result:
1, 3, 4
Expression:
let $data := {
  "fr": { "capital": "Paris", "languages": [ "French" ] }, 
  "de": { "capital": "Berlin", "languages": [ "German" ] }
}
return pin($data)??languages[. = 'German'] ! label(.)?path()[1]
Result:
"de"