<!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><!--DO NOT EDIT: GENERATED BY merge-function-specs.xsl--><spec xmlns:e="http://www.w3.org/1999/XSL/Spec/ElementSyntax" id="spec-top" w3c-doctype="rec" status="ext-review"><header><title>XPath and XQuery Functions and Operators 4.0</title><version/><w3c-designation>REC-xpath-functions-40</w3c-designation><w3c-doctype>W3C Editor's Draft</w3c-doctype><pubdate><day>01</day><month>January</month><year>2000</year></pubdate><publoc>
            <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://qt4cg.org/specifications/xpath-functions-40/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://qt4cg.org/specifications/xpath-functions-40/</loc>
        </publoc><altlocs><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="xpath-functions-40.xml" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Specification in XML format</loc><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="function-catalog.xml" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XML function catalog</loc></altlocs><latestloc doc="XPath and XQuery Functions and Operators 4.0">
            <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://qt4cg.org/specifications/xpath-functions-40/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://qt4cg.org/specifications/xpath-functions-40/</loc>
        </latestloc><prevrec doc="XPath and XQuery Functions and Operators">
    <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2017/REC-xpath-functions-31-20170321/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.w3.org/TR/2017/REC-xpath-functions-31-20170321/</loc>
  </prevrec><authlist><author><name>Michael Kay</name><affiliation>Saxonica</affiliation><email xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.saxonica.com/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">http://www.saxonica.com/</email></author></authlist><status><p><emph>This section describes the status of this document at the time of its publication.
               Other documents may supersede this document.</emph></p><p>This document is a working draft developed and maintained by a W3C Community Group,
            the <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/community/xslt-40/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">XQuery and XSLT Extensions Community Group</loc>
            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.</p><p>The community group welcomes comments on the specification. Comments are best submitted
         as issues on the group's <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://github.com/qt4cg/qtspecs/issues" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">GitHub repository</loc>.</p><?at-risk?><p>The community group maintains two extensive test suites, 
            one oriented to XQuery and XPath, the other to XSLT.
         These can be found at <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://github.com/qt4cg/qt4tests" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">qt4tests</loc> and
         <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://github.com/qt4cg/xslt40-test" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">xslt40-test</loc> 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.</p><note role="dedication" id="dedication"><p>The publications of this community group 
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="../xquery-40/xpath-40.html#dedication" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">are dedicated</loc> to our co-chair,
Michael Sperberg-McQueen (1954–2024).</p></note></status><abstract><p>This document defines constructor functions, operators, and functions on the datatypes defined in
                    <bibref ref="xmlschema-2"/> and the datatypes defined in <bibref ref="xpath-datamodel-40"/>.  It also defines
                functions and operators on nodes and node sequences as defined in the <bibref ref="xpath-datamodel-40"/>.  These functions and operators are defined for use in <bibref ref="xpath-40"/> and <bibref ref="xquery-40"/> and
                    <bibref ref="xslt-40"/> and other related XML standards.  The signatures and summaries of functions defined in this document are available at:
<loc xmlns:xlink="http://www.w3.org/1999/xlink" href="http://www.w3.org/2005/xpath-functions/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/2005/xpath-functions/</loc>.</p><p>A summary of changes since version 3.1 is provided at <specref ref="changelog"/>.</p></abstract><langusage><language id="EN">English</language></langusage><revisiondesc><p/></revisiondesc></header><body><div1 id="intro"><head>Introduction</head><changes><change>If a section of this specification has been updated since version 3.1,
                an overview of the changes is provided, along with links to
                navigate to the next or previous change.</change><change>Sections with significant changes are marked with a ✭ symbol in the
                table of contents. New functions are indicated by ✚.</change></changes><p>The purpose of this document is to define functions and operators for inclusion in
                XPath 4.0, XQuery 4.0, and XSLT 4.0. 
                The exact syntax used to call these
                functions and operators is specified in <bibref ref="xpath-40"/>, <bibref ref="xquery-40"/> and 
            <bibref ref="xslt-40"/>. </p><p>This document defines three classes of functions:</p><ulist><item><p>General purpose functions, available for direct use in user-written queries, stylesheets, and XPath expressions,
               whose arguments and results are values defined by the <bibref ref="xpath-datamodel-40"/>.</p></item><item><p>Constructor functions, used for creating instances of a datatype from values of (in general) a different
            datatype. These functions are also available for general use; they are named after the datatype that they return,
            and they always take a single argument.</p></item><item><p>Functions that specify the semantics of operators defined in <bibref ref="xpath-40"/> and <bibref ref="xquery-40"/>.
            These exist for specification purposes only, and are not intended for direct calling from user-written code.</p></item></ulist><p>
                <bibref ref="xmlschema-2"/> defines a number of primitive and derived datatypes,
                collectively known as built-in datatypes. This document defines functions and
                operations on these datatypes as well as the other types 
                (for example, nodes and sequences of nodes) defined in <xspecref spec="DM31" ref="types"/> of 
            the <bibref ref="xpath-datamodel-40"/>.
                These functions and operations are available for use in <bibref ref="xpath-40"/>,
                    <bibref ref="xquery-40"/> and any other host language that chooses to reference them.
                In particular, they may be referenced in future versions of XSLT and related XML standards. </p><p><bibref ref="xmlschema11-2"/> adds to the datatypes defined
            in <bibref ref="xmlschema-2"/>. It introduces a new derived type <code nobreak="false">xs:dateTimeStamp</code>, and it
         incorporates as built-in types the two types <code nobreak="false">xs:yearMonthDuration</code> and <code nobreak="false">xs:dayTimeDuration</code>
         which were previously XDM additions to the type system. In addition, XSD 1.1 clarifies and updates many
         aspects of the definitions of the existing datatypes: for example, it extends the value space of
         <code nobreak="false">xs:double</code> to allow both positive and negative zero, and extends the lexical space to allow <code nobreak="false">+INF</code>;
            it modifies the value space of <code nobreak="false">xs:Name</code>
         to permit additional Unicode characters; it allows year zero and disallows leap seconds in <code nobreak="false">xs:dateTime</code>
         values; and it allows any character string to appear as the value of an <code nobreak="false">xs:anyURI</code> item.
         Implementations of this specification <rfc2119>may</rfc2119> support either XSD 1.0 or XSD 1.1 when
            performing schema-based validation, but in all other respects, the type system follows XSD 1.1.</p><p>References to specific sections of some of the above documents are indicated by
                cross-document links in this document. Each such link consists of a pointer to a
                specific section followed a superscript specifying the linked document. The
                superscripts have the following meanings: XQ <bibref ref="xquery-40"/>, XT <bibref ref="xslt-40"/>,
            XP <bibref ref="xpath-40"/>, and DM <bibref ref="xpath-datamodel-40"/>.</p><div2 id="operators" diff="add" at="2022-12-20"><head>Operators</head><p>Despite its title, this document does not attempt to define the semantics of all the operators available
               in the <bibref ref="xpath-40"/> language; indeed, in the interests of avoiding duplication, the majority of
               operators are now defined entirely within <bibref ref="xpath-40"/> (for XQuery, the definitions are also found
               in <bibref ref="xquery-40"/>, and are generally identical).</p><p>The remaining operators that are described in this publication are the arithmetic operators, 
               where the semantics of the operator
            depend on the types of the arguments. For these operators, the language specification describes rules for selecting
            an internal function defined in this specification to underpin the operator. For example, when the operator <code nobreak="false">x+y</code>
            is applied to two operands of type <code nobreak="false">xs:double</code>, the function <code nobreak="false">op:numeric-add</code> is selected.</p><note><p>Previous versions of this specification also defined the value comparison operators such as 
                  <code nobreak="false">eq</code>, <code nobreak="false">lt</code>, and <code nobreak="false">gt</code> in terms of functions such as
            <code role="example" nobreak="false">op:date-greater-than</code>. These have been dropped; for most data types the semantics
                  of the value comparison operators are defined by reference to the <function>fn:compare</function> function.</p></note></div2><div2 id="conformance"><head>Conformance</head><changes><change issue="205" PR="326" date="2023-02-01">Higher-order functions are no longer an optional feature.</change></changes><p>
               This recommendation contains a set of function specifications. 
               It defines conformance at the level of individual functions. An implementation of a function conforms to a function specification 
               in this recommendation if all the following conditions are satisfied:</p><ulist><item><p>For all combinations of valid inputs to the function (both explicit arguments and implicit context dependencies), 
                  the result of the function meets the mandatory requirements of this specification.
               </p></item><item><p>For all invalid inputs to the function, the implementation raises (in some way appropriate to the calling environment) a dynamic error.
               </p></item><item><p>For a sequence of calls within the same <termref def="execution-scope">execution scope</termref>, the requirements of this recommendation 
                  regarding the <termref def="dt-deterministic">determinism</termref> of results are satisfied (see <specref ref="properties-of-functions"/>).
               </p></item></ulist><p>Other recommendations (“host languages”) that reference this document may dictate:</p><ulist><item><p>Subsets or supersets of this set of functions to be available in particular environments;</p></item><item><p>Mechanisms for invoking functions, supplying arguments, initializing the static and dynamic context, receiving results, and handling errors;
               </p></item><item><p>A concrete realization of concepts such as <termref def="execution-scope">execution scope</termref>;</p></item><item><p>Which versions of other specifications referenced herein (for example, XML, XSD, or Unicode) are to be used.</p></item></ulist><p>Any behavior that is discretionary (implementation-defined or implementation-dependent) in this specification may be constrained by a host language.</p><note><p>Adding such constraints in a host language, however, is discouraged because it makes it difficult to reuse implementations of 
               the function library across host languages.</p></note><p>This specification allows flexibility in the choice of versions of specifications on which it depends:</p><ulist><item><p>It is <termref def="implementation-defined"/> which version of Unicode is supported, 
                     but it is recommended that the most recent version of Unicode be used.  </p></item><item><p>It is <termref def="implementation-defined"/> whether the type system is based
                     on XML Schema 1.0 or XML Schema 1.1.  </p></item><item><p>It is <termref def="implementation-defined"/> whether definitions that rely on
                     XML (for example, the set of valid XML characters) should use the definitions in XML 1.0 or XML 1.1.</p></item></ulist><note><p>The XML Schema 1.1 recommendation
                  introduces one new concrete datatype: <code nobreak="false">xs:dateTimeStamp</code>; it also incorporates
                  the types <code nobreak="false">xs:dayTimeDuration</code>, <code nobreak="false">xs:yearMonthDuration</code>,
                  and <code nobreak="false">xs:anyAtomicType</code> which were previously defined in earlier versions of <bibref ref="xpath-datamodel-40"/>.
                  Furthermore, XSD 1.1
                  includes the option of supporting revised definitions of types such as <code nobreak="false">xs:NCName</code>
                  based on the rules in XML 1.1 rather than 1.0.</p></note><p diff="add" at="2023-06-12">The <bibref ref="xpath-datamodel-40"/> allows flexibility in the
            repertoire of characters permitted during processing that goes beyond even what
            version of XML is supported. A processor
            <rfc2119>may</rfc2119> allow the user to construct nodes
            and atomic items that contain characters not allowed by any version of
            XML.
            <termdef id="dt-permitted-character" term="permitted character">A <term>permitted character</term>
            is one within the repertoire accepted by the implementation.</termdef></p><p>In this document, text labeled as an example or as a note is
            provided for explanatory purposes and is not normative.</p></div2><div2 id="namespace-prefixes"><head>Namespaces and prefixes</head><p>The functions and operators defined in this document are contained in one of
                    several namespaces (see <bibref ref="xml-names"/>) and referenced using an
                    <code nobreak="false">xs:QName</code>.</p><p>This document uses conventional prefixes to refer to these namespaces. User-written
               applications can choose a different prefix to refer to the namespace, so long as it is
               bound to the correct URI. The host language may also define a default namespace for
               function calls, in which case function names in that namespace need not be prefixed
               at all. In many cases the default namespace will be 
               <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>, allowing a call on the <function>fn:name</function>
               function (for example) to be written as <code nobreak="false">name()</code> rather than <code nobreak="false">fn:name()</code>; 
               in this document, however, all example function calls are explicitly prefixed.</p><p>The URIs of the namespaces and the conventional prefixes associated with them are:</p><ulist><item><p><code nobreak="false">http://www.w3.org/2001/XMLSchema</code> for constructors —
                            associated with <code nobreak="false">xs</code>.
                  </p><p>The section <specref ref="constructor-functions"/> defines 
                     constructor functions for the built-in datatypes defined
                     in <bibref ref="xmlschema-2"/> and in <xspecref spec="DM31" ref="types"/>
                     of <bibref ref="xpath-datamodel-40"/>. These datatypes and the corresponding constructor functions  
                     are in the XML Schema namespace, <code nobreak="false">http://www.w3.org/2001/XMLSchema</code>,
                     and are named in this document using the <code nobreak="false">xs</code> prefix. </p></item><item><p><code nobreak="false">http://www.w3.org/2005/xpath-functions</code>
                     for functions — associated with <code nobreak="false">fn</code>. </p><p>The namespace
                     prefix used in this document for most functions that are available to users is
                     <code nobreak="false">fn</code>.</p></item><item><p><code nobreak="false">http://www.w3.org/2005/xpath-functions/math</code>
                     for functions — associated with <code nobreak="false">math</code>. </p><p>This namespace is used for some mathematical functions. The namespace
                     prefix used in this document for these functions is <code nobreak="false">math</code>.
                     These functions are available to users in exactly the same way as those in the
                     <code nobreak="false">fn</code> namespace.</p></item><item><p><code nobreak="false">http://www.w3.org/2005/xpath-functions/map</code>
                     for functions — associated with <code nobreak="false">map</code>. </p><p>This namespace is used for some functions that manipulate maps (see
                     <specref ref="map-functions"/>). The namespace
                     prefix used in this document for these functions is <code nobreak="false">map</code>.
                     These functions are available to users in exactly the same way as those in the
                     <code nobreak="false">fn</code> namespace.</p></item><item><p><code nobreak="false">http://www.w3.org/2005/xpath-functions/array</code>
                     for functions — associated with <code nobreak="false">array</code>. </p><p>This namespace is used for some functions that manipulate maps (see
                     <specref ref="array-functions"/>). The namespace
                     prefix used in this document for these functions is <code nobreak="false">array</code>.
                     These functions are available to users in exactly the same way as those in the
                     <code nobreak="false">fn</code> namespace.</p></item><item><p><code nobreak="false">http://www.w3.org/2005/xqt-errors</code> — associated with
                            <code nobreak="false">err</code>. </p><p>There are no functions in this namespace; it is used for error codes.</p><p>This document uses the prefix <code nobreak="false">err</code> to represent the namespace URI 
                     <code nobreak="false">http://www.w3.org/2005/xqt-errors</code>, which is the namespace for all XPath 
                     and XQuery error codes and messages. This namespace prefix is not predeclared and 
                     its use in this document is not normative.</p></item><item><p><code nobreak="false">http://www.w3.org/2010/xslt-xquery-serialization</code> — associated with
                     <code nobreak="false">output</code>. </p><p>There are no functions in this namespace: it is
                     used for serialization parameters, as described in <bibref ref="xslt-xquery-serialization-31"/></p></item><item><p>
                     Functions defined with the <code nobreak="false">op</code> prefix are described here to
                     underpin the definitions of the operators in <bibref ref="xpath-40"/>, <bibref ref="xquery-40"/> 
                     and <bibref ref="xslt-40"/>. These functions are not available
                     directly to users, and there is no requirement that implementations should
                     actually provide these functions. For this reason, no namespace is associated
                     with the <code nobreak="false">op</code> prefix. For example, multiplication is generally
                     associated with the <code nobreak="false">*</code> operator, but it is described as a function
                     in this document:</p><example role="signature"><proto role="example" name="numeric-multiply" return-type="xs:numeric" isOp="yes" prefix="op" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:numeric"/><arg name="arg2" type="xs:numeric"/></proto></example><p diff="add" at="2022-12-20">Sometimes there is a need to use an operator as a function.
                  To meet this requirement, the function <function>fn:op</function> takes any simple binary operator as its argument,
                  and returns a corresponding function. So for example <code nobreak="false">fn:for-each-pair($seq1, $seq2, op("+"))</code>
                  performs a pairwise addition of the values in two input sequences.</p></item></ulist><note><p>The above namespace URIs are not expected to change from one version of this 
                  document to another. The contents of these namespaces may be extended to allow 
                  additional functions (and errors, and serialization parameters) to be defined.</p></note></div2><div2 id="func-overloading"><head>Function overloading</head><p>A function is uniquely defined by its name and arity (number of arguments); it is therefore
            not possible to have two different functions that have the same name and arity, but different
            types in their signature. That is, function overloading in this sense of the term is not permitted.
            Consequently, functions such as <function>fn:string</function> which accept arguments of many different
            types have a signature that defines a very general argument type, in this case <code nobreak="false">item()?</code>
            which accepts any single item; supplying an inappropriate item (such as a function item) causes
            a dynamic error.</p><p>Some functions on numeric types include the type <code nobreak="false">xs:numeric</code> in their signature
               as an argument or result type. In this version of the specification, <code nobreak="false">xs:numeric</code>
               has been redefined as a built-in union type representing the union of 
               <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:float</code>, <code nobreak="false">xs:double</code> (and thus automatically
               accepting types derived from these, including <code nobreak="false">xs:integer</code>).</p><p>Operators such as <code nobreak="false">+</code> may be overloaded: they map to different underlying functions depending
            on the dynamic types of the supplied operands.</p><p>It is possible for two functions to have the same name provided they have different arity (number of arguments).
               For the functions defined in this specification, where two functions have the same name and different arity,
               they also have closely related behavior, so they are defined in the same section of this document.</p></div2><div2 id="func-signatures"><head>Function signatures and descriptions</head><p>Each function (or group of functions having the same name) is defined in this specification using
            a standard proforma. This has the following sections:</p><div3 id="id-function-signatures-name"><head>Function name</head><p>The function name is a <code nobreak="false">QName</code> as defined in <bibref ref="xmlschema-2"/>
                  and must adhere to its syntactic conventions. Following the precedent set by <bibref ref="xpath"/>,
                  function names are generally composed of English words separated by hyphens: 
                  specifically <char>U+002D</char>. Abbreviations are
                  used only where there is a strong precedent in other programming languages (as with <code nobreak="false">math:sin</code> and 
                  <code nobreak="false">math:cos</code> for sine and cosine). If a
                  function name contains a <bibref ref="xmlschema-2"/> datatype name, it may have
                  intercapitalized spelling and is used in the function name as such. An example is <function>fn:timezone-from-dateTime</function>.</p></div3><div3 id="id-function-signatures-summary"><head>Function summary</head><p>The first section in the proforma is a short summary of what the function does. This is intended
                to be informative rather than normative.</p></div3><div3 id="id-function-signatures-signature"><head>Function signature</head><p>Each function is then defined by specifying its signature(s), which define the
                  types of the parameters and of the result value.</p><p diff="add" at="2022-11-29">Where functions take a variable number of arguments, two conventions are used:</p><ulist diff="add" at="2022-11-29"><item><p>Wherever possible, a single function signature is used giving default values
                  for those parameters that can be omitted.</p></item><item><p>If this is not possible, because the effect of omitting a parameter cannot
                  be specified by giving a default value, multiple signatures are given for the function.</p></item></ulist><p>Each function signature is presented in a form like this:</p><example role="signature"><proto role="example" name="function-name" return-type="return-type" returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="parameter-name" type="parameter-type"/><arg name="..." type=""/></proto></example><p>In this notation, <term>function-name</term>, in bold-face, is the 
                  <phrase diff="add" at="2023-01-17">local</phrase> name of the
                       function whose signature is being specified. <phrase>The prefix <term>fn</term>
                       indicates that the function is in the namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>:
                          this is one of the conventional prefixes listed in <specref ref="namespace-prefixes"/>.</phrase>
                       If the function takes no
                       parameters, then the name is followed by an empty parameter list:
                       <code nobreak="false">()</code>; otherwise, the name is followed by a parenthesized list of
                       parameter declarations. Each parameter declaration includes:</p><ulist diff="add" at="2022-11-29"><item><p>The name of the parameter (which in 4.0 is significant because it can be used
                  as a keyword in a function call)</p></item><item><p>The static type of the parameter (in italics)</p></item><item><p>If the parameter is optional, then an expression giving the default value 
                     (preceded by the symbol <code nobreak="false">:=</code>).</p><p diff="add" at="2023-12-04">The default value expression is evaluated using the static and
                        dynamic context of the function caller (or of a named function reference). For example, 
                        if the default value is given as <code nobreak="false">.</code>, then it evaluates to the context value 
                        from the dynamic context of the function caller; if it is given as <code nobreak="false">default-collation</code>,
                        then its value is the default collation from the static context of the function caller;
                        if it is given as <code nobreak="false">deep-equal#2</code>, then the third argument supplied to <code nobreak="false">deep-equal</code>
                        is the default collation from the static context of the caller.</p></item></ulist><note><p id="default-on-empty">
                  If no argument is supplied for a parameter that has a default value, the default
                  value is used. If the parameter is marked <code nobreak="false">(:default-on-empty:)</code>,
                  the default value is also used when the supplied argument is the empty sequence.
                  Otherwise, the empty sequence is treated according to the function-specific rules.</p><p>The marker is only used on parameters that have default values.</p></note><p>If there are two or more parameter declarations, they are separated by a comma.</p><p>The <emph> <code nobreak="false">return-type</code></emph>, also in italics, specifies the static type of the value returned by the
                       function. The dynamic type of the value returned by the function is the same as its static
                       type or derived from the static type. All parameter types and return types are
                       specified using the SequenceType notation defined in <xspecref spec="XP40" ref="id-sequencetype-syntax"/>.</p></div3><div3 id="id-function-signatures-rules"><head>Function rules</head><p>The next section in the proforma defines the semantics of the function as a set of rules. 
                  The order in which the rules appear is significant; they are to be applied in the order in which
                  they are written. Error conditions, however, are generally listed in a separate section that follows
               the main rules, and take precedence over non-error rules except where otherwise stated. The principles outlined
               in <xspecref spec="XP40" ref="id-errors-and-opt"/> apply by default: to paraphrase, if the result of the function
               can be determined without evaluating all its arguments, then it is not necessary to evaluate the remaining arguments
               merely in order to determine whether any error conditions apply.</p></div3><div3 id="id-function-signatures-formal-specification"><head>Formal Equivalents</head><p>Some functions supplement the prose rules with a more formal specification that describes the effect
               of the function in terms of an equivalent XPath or XQuery implementation. This is intended to take
               precedence over the prose rules in the event of any conflict; however, both sections are intended
               to be complete and not to rely on each other.</p><p>In writing the formal equivalents, a number of guidelines have been followed:</p><olist><item><p>Where the equivalent code calls other functions, these should either be primitives
                  defined in the data model specification (see <bibref ref="xpath-datamodel-40"/>), or
                  functions that themselves have a formal equivalent; and the dependencies should not
                  be circular.</p></item><item><p>There should be minimal reliance on XPath or XQuery language features.
                  Although no attempt has been made to precisely define a core set of language constructs,
                  the specifications try to avoid relying on features other than function calls
                  and a few basic operators including the comma operator, equality testing, and
                  simple integer arithmetic.</p></item><item><p>There is no suggestion that the formal equivalent is a practical
                     implementation; in many cases it might have very poor performance.</p></item><item><p>In some cases the formal equivalent does not attempt to replicate
                     correct behavior in error cases; if so, this is always clearly stated.</p></item><item><p>The formal equivalent will always produce a conformant result for the
                     function, but in some cases this will not be the only possible conformant result.</p></item></olist><ednote><edtext>This worthy intent is not yet fully achieved; for example there are
               formal specifications that invoke fn:atomic-equal.</edtext></ednote><p>There is no attempt to write formal equivalents for functions that have complex logic
               (such as <function>fn:format-number</function>) or dependencies (such as <function>fn:doc</function>); the aim
               of the formal equivalents is to define as rigorously as possible a platform of basic
               functionality that can be used as a solid foundation for more complex features.</p></div3><div3 id="id-function-signatures-notes"><head>Notes</head><p>Where the proforma includes a section headed <emph>Notes</emph>, these are non-normative.</p></div3><div3 id="id-function-signatures-examples"><head>Examples</head><p>Where the proforma includes a section headed <emph>Examples</emph>, these are non-normative.</p><p>Many of the examples are given in structured form, showing example expressions and their expected results.
               These published examples are derived from executable test cases, so they follow a standard format. In general,
               the actual result of the expression is expected to be deep-equal to the presented result, under the
               rules of the <function>fn:deep-equal</function> function with default options. In some cases the result is qualified
               to indicate that the order of items in the result is implementation-dependent, or that numeric results
               are approximate.</p><p>For more complex functions, examples may be given using informal narrative prose.</p></div3></div2><div2 id="id-function-calls"><head>Function calls</head><p>Rules for evaluating the operands of operators are described in the relevant sections
                    of <bibref ref="xquery-40"/> and <bibref ref="xpath-40"/>. For example, the rules for
                    evaluating the operands of arithmetic operators are described in <xspecref spec="XP40" ref="id-arithmetic"/>. 
               Specifically, rules for parameters of
                    type <code nobreak="false">xs:untypedAtomic</code> and the empty sequence are specified in this section.</p><p>For function calls, the required type of an argument is defined in the function
               signature of each function, and the way in which a supplied value is converted to the
               required type (or rejected if it cannot be converted) is defined by the
               <xtermref spec="XP40" ref="dt-coercion-rules"/>.</p><p>Some functions accept a single value or the empty sequence as an argument and
                    some may return a single value or the empty sequence. This is indicated in the
                    function signature by following the parameter or return type name with a
                    question mark: <code nobreak="false">?</code>, indicating that either a single value or the
                    empty sequence must appear. See below.</p><example role="signature"><proto role="example" name="function-name" return-type="return-type" returnEmptyOk="yes" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="parameter-name" type="parameter-type" emptyOk="yes"/></proto></example><p>Note that this function signature is different from a signature in which the
                    parameter is omitted. See, for example, the two signatures
                    for <function>fn:string</function>. In the first signature, the parameter is omitted
                    and the argument defaults to the context value, referred to as <code nobreak="false">.</code>.
                    In the second signature, the argument must be present but may be the empty
                    sequence, written as <code nobreak="false">()</code>.
                </p><p>Some functions accept a sequence of zero or more values as an argument. This is
                    indicated by following the name of the type of the items in the sequence with
                    <code nobreak="false">*</code>. The sequence may contain zero or more items of the named type.
                    For example, the function below accepts a sequence of <code nobreak="false">xs:double</code> and
                    returns a <code nobreak="false">xs:double</code> or the empty sequence.</p><example role="signature"><proto role="example" name="median" return-type="xs:double" returnEmptyOk="yes" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="arg" type="xs:double*" emptyOk="no"/></proto></example><p diff="add" at="A">In XPath 4.0, the arguments in a function call can be supplied by
            keyword as an alternative to supplying them positionally. For example the call
            <code nobreak="false">resolve-uri(@href, static-base-uri())</code> can now be written 
            <code nobreak="false">resolve-uri(base := static-base-uri(), href := @href)</code>. The order in which
            arguments are supplied can therefore differ from the order in which they are declared.
            The specification, however, continues to use phrases such as “the second argument” as a 
            convenient shorthand for "the value of the argument that is bound to the second parameter 
            declaration".</p></div2><div2 id="options"><head>Options</head><changes><change issue="1019" PR="1059" date="2024-03-26">
                  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.
               </change></changes><p>As a matter of convention, a number of functions defined in this document take
            a parameter whose value is a map, defining options controlling the detail of how
            the function is evaluated. Maps are a new datatype introduced in XPath 3.1.</p><p>For example, the function <function>fn:xml-to-json</function> has an options parameter
            allowing specification of whether the output is to be indented. A call might be written:</p><eg xml:space="preserve">xml-to-json($input, { 'indent': true() })</eg><p><termdef id="option-parameter-conventions" term="option parameter conventions">Functions
            that take an options parameter adopt common conventions on how the
            options are used. These are referred to as the <term>option parameter conventions</term>. These
            rules apply only to functions that explicitly refer to them.</termdef></p><p>Where a function adopts the <termref def="option-parameter-conventions"/>, the following rules
            apply:</p><olist><item><p>The value of the relevant argument must be a map. The entries in the map are
                  referred to as options: the key of the entry is called the option name, and the
                  associated value is the option value. Option names defined in this specification
               are always strings (single <code nobreak="false">xs:string</code> values). Option values may
               be of any type.</p></item><item><p>The type of the options parameter in the function signature is always
               given as <code nobreak="false">map(*)</code>.</p></item><item><p>Although option names are described above as strings, the actual key may be
                  any value that is the <termref def="dt-same-key"/> as the required string. 
                  For example, instances of <code nobreak="false">xs:untypedAtomic</code>
                  or <code nobreak="false">xs:anyURI</code> are equally acceptable.</p><note><p>This means that the implementation of the function can check for the
               presence and value of particular options using the functions <function>map:contains</function>
               and/or <function>map:get</function>.</p></note></item><item><p>Implementations <rfc2119>may</rfc2119> attach an 
                  <termref def="implementation-defined">implementation-defined</termref> meaning to
                  options in the map that are not described in this specification. These options
                  <rfc2119>should</rfc2119> use values of type <code nobreak="false">xs:QName</code> as the option
                  names, using an appropriate namespace.</p></item><item><p>If an option is present whose key is not described in the specification, 
                  then a type error <xerrorref spec="XP" class="TY" code="0004"/> <rfc2119>must</rfc2119> 
                  be raised unless either (a) the key is recognized by the implementation, 
                  or (b) the key is a value of type
                  <code nobreak="false">xs:QName</code> with a non-absent namespace.</p></item><item><p>All entries in the options map are optional, and supplying the empty map has the same
               effect as omitting the relevant argument in the function call, assuming this is permitted.</p></item><item><p>The ordering of the options map is immaterial.</p></item><item><p>For each named option, the function
               specification defines a required type for the option value. The value that is actually
               supplied in the map is converted to this required type using the 
                  <xtermref spec="XP40" ref="dt-coercion-rules">coercion rules</xtermref>.
                  This will result in an error (typically 
                     <xerrorref spec="XP" class="TY" code="0004" type="type"/> or
                     <xerrorref spec="FO" class="RG" code="0001" type="type"/>)
                  if conversion of the supplied value to the required type is not possible. 
                  A type error also occurs if this conversion
                  delivers a coerced function whose invocation fails with a type error.
                  A dynamic error occurs if the supplied value 
               after conversion is not one of the permitted values for the option in question: the error codes
               for this error are defined in the specification of each function.</p><note><p>It is the responsibility of each function implementation to invoke this conversion; it
               does not happen automatically as a consequence of the function-calling rules.</p></note></item><item><p>In cases where the value of an option is itself a map, the specification
               of the particular function must indicate whether or not these rules apply recursively 
               to the contents of that map.</p></item></olist></div2><div2 id="datatypes"><head>Type System</head><p>The diagrams in this section show how nodes, functions,
primitive simple types,
and user defined types fit together into a type system.
This type system comprises two distinct subsystems that both include
the primitive atomic types. 
In the diagrams, connecting lines represent relationships between derived types
and the types from which they are derived;
the former are always below and to the right of the latter.
</p><p>The <code nobreak="false">xs:IDREFS</code>, <code nobreak="false">xs:NMTOKENS</code>,
<code nobreak="false">xs:ENTITIES</code> types, and <code nobreak="false">xs:numeric</code> and both the
<code nobreak="false">user-defined list types</code> and
<code nobreak="false">user-defined union types</code>
are special types in that these types are lists or unions
rather than types derived by extension or restriction.</p><div3 id="item-type-hierarchy"><head>Item Types</head><p>The first diagram illustrates
the relationship of various item types.</p><p>Item types are used to characterize the various types of item that can appear
      in a sequence (nodes, atomic items, and functions), and they are therefore used
      in declaring the types of variables or the argument types and result types of functions.</p><p>In XDM, item types include node types,
function types, and built-in atomic types. 
Item types form a directed graph, rather than a
hierarchy or lattice: in the relationship defined by the
<code nobreak="false">derived-from(A, B)</code> function, some types are derived from
more than one other type. Examples include functions
(<code nobreak="false">function(xs:string) as xs:int</code> is substitutable for
<code nobreak="false">function(xs:NCName) as xs:int</code> and also for
<code nobreak="false">function(xs:string) as xs:decimal</code>), and choice types
(<code nobreak="false">A</code> is substitutable for the choice type <code nobreak="false">(A | B)</code> and also
for <code nobreak="false">(A | C)</code>. Record types provide an alternative way of categorizing
   maps: the instances of <code nobreak="false">record(longitude, latitude)</code> overlap with
   the instances of <code nobreak="false">map(xs:string, xs:double)</code>. The diagram, which shows
only hierarchic relationships, is therefore a simplification of the
full model.</p><p role="type-hierarchy-figure">
<ulist role="type-hierarchy type-colors"><item role="abstract"><p role="root"><phrase>item</phrase><phrase role="kind"> (abstract)</phrase></p><ulist><item role="abstract built-in-atomic"><p>
          <phrase><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#th_anyAtomicType" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">anyAtomicType</loc></phrase>
          <phrase role="kind"> (built-in atomic)</phrase>
        </p></item><item role="abstract node"><p><phrase>GNode</phrase><phrase role="kind"> (node)</phrase></p><ulist><item role="abstract node"><p><phrase>XNode</phrase><phrase role="kind"> (node)</phrase></p><ulist><item role="node"><p><phrase>attribute</phrase><phrase role="kind"> (node)</phrase></p><ulist><item role="node user-defined"><p>
                       <phrase>user-defined attribute types</phrase>
                       <phrase role="kind"> (user-defined)</phrase>
                    </p></item></ulist></item><item role="node"><p><phrase>document</phrase><phrase role="kind"> (node)</phrase></p><ulist><item role="node user-defined"><p>
                        <phrase>user-defined document types</phrase>
                        <phrase role="kind"> (user-defined)</phrase>
                     </p></item></ulist></item><item role="node"><p><phrase>element</phrase><phrase role="kind"> (node)</phrase></p><ulist><item role="node user-defined"><p>
                        <phrase>user-defined element types</phrase>
                        <phrase role="kind"> (user-defined)</phrase>
                     </p></item></ulist></item><item role="node"><p><phrase>text</phrase><phrase role="kind"> (node)</phrase></p></item><item role="node"><p><phrase>comment</phrase><phrase role="kind"> (node)</phrase></p></item><item role="node"><p><phrase>processing-instruction</phrase><phrase role="kind"> (node)</phrase></p></item><item role="node"><p><phrase>namespace</phrase><phrase role="kind"> (node)</phrase></p></item></ulist></item><item role="node"><p><phrase>JNode</phrase><phrase role="kind"> (node)</phrase></p></item></ulist></item><item role="abstract function"><p><phrase>function</phrase><phrase role="kind"> (function item)</phrase></p><ulist><item role="function user-defined"><p>
                <phrase>user-defined function item types</phrase>
                <phrase role="kind"> (user-defined)</phrase>
             </p></item><item role="abstract function"><p><phrase>array</phrase><phrase role="kind"> (function item)</phrase></p><ulist><item role="function user-defined"><p>
                    <phrase>user-defined array types</phrase>
                    <phrase role="kind"> (user-defined)</phrase>
                 </p></item></ulist></item><item role="abstract function"><p><phrase>map</phrase><phrase role="kind"> (function item)</phrase></p><ulist><item role="function user-defined"><p>
                    <phrase>user-defined map types</phrase>
                    <phrase role="kind"> (user-defined)</phrase>
                 </p></item><item role="function user-defined"><p>
                    <phrase>user-defined record types</phrase>
                    <phrase role="kind"> (user-defined)</phrase>
                 </p></item></ulist></item></ulist></item></ulist></item></ulist>
<ulist role="type-hierarchy type-colors legend"><item><p role="root"><phrase>Supertype</phrase></p><ulist><item><p><phrase>subtype</phrase></p></item></ulist></item></ulist>
<ulist role="type-legend type-colors legend"><item role="abstract"><p>
         <phrase>Abstract types</phrase>
         <phrase role="kind"> (abstract)</phrase>
      </p></item><item role="built-in-atomic"><p>
         <phrase>Built-in atomic types</phrase>
         <phrase role="kind"> (built-in atomic)</phrase>
      </p></item><item role="node"><p>
         <phrase>Node types</phrase>
         <phrase role="kind"> (node)</phrase>
      </p></item><item role="function"><p>
         <phrase>Function item types</phrase>
         <phrase role="kind"> (function item)</phrase>
      </p></item><item role="user-defined"><p>
         <phrase>User-defined types</phrase>
         <phrase role="kind"> (user-defined)</phrase>
      </p></item></ulist>
</p></div3><div3 id="schema-type-hierarchy"><head>Schema Type Hierarchy</head><p>The next diagram illustrate the schema type subsystem, in which
all types are derived from <code nobreak="false">xs:anyType</code>. </p><p>Schema types include built-in types defined in the XML Schema specification, and user-defined
      types defined using mechanisms described in the XML Schema specification. Schema types define the
      permitted contents of nodes. The main categories are complex types, which define the permitted content
      of elements, and simple types, which can be used to constrain the values of both elements and attributes.</p><p role="type-hierarchy-figure">
   <ulist role="type-hierarchy type-colors"><item role="abstract root"><p role="root">
            <phrase>XML Schema types</phrase>
            <phrase role="kind"> (abstract)</phrase>
         </p><ulist><item role="built-in-complex"><p role="first">
                  <phrase>anyType</phrase>
                  <phrase role="kind"> (built-in complex)</phrase>
               </p><ulist><item role="abstract"><p role="first">
                        <phrase>Simple types</phrase>
                        <phrase role="kind"> (abstract)</phrase>
                     </p><ulist><item role="built-in-list"><p role="first">
                              <phrase>anySimpleType</phrase>
                              <phrase role="kind"> (built-inlist)</phrase>
                           </p><ulist><item role="abstract"><p role="first">
                                    <phrase>Atomic types</phrase>
                                    <phrase role="kind"> (abstract)</phrase>
                                 </p><ulist><item role="built-in-atomic"><p role="first">
                                          <phrase><loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#th_anyAtomicType" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">anyAtomicType</loc></phrase>
                                          <phrase role="kind"> (built-in atomic)</phrase>
                                       </p></item></ulist></item><item role="abstract"><p role="item">
                                    <phrase>list types</phrase>
                                    <phrase role="kind"> (abstract)</phrase>
                                 </p><ulist><item role="built-in-list"><p role="item">
                                          <phrase>ENTITIES</phrase>
                                          <phrase role="kind"> (built-in list)</phrase>
                                       </p></item><item role="built-in-list"><p role="first">
                                          <phrase>IDREFS</phrase>
                                          <phrase role="kind"> (built-in list)</phrase>
                                       </p></item><item role="built-in-list"><p role="item">
                                          <phrase>NMTOKENS</phrase>
                                          <phrase role="kind"> (built-in list)</phrase>
                                       </p></item><item role="user-defined"><p role="last">
                                          <phrase>user-defined list types</phrase>
                                          <phrase role="kind"> (user-defined)</phrase>
                                       </p></item></ulist></item><item role="abstract"><p role="last">
                                    <phrase>union types</phrase>
                                    <phrase role="kind"> (abstract)</phrase>
                                 </p><ulist><item role="built-in-complex"><p role="first">
                                          <phrase>numeric</phrase>
                                          <phrase role="kind"> (built-in complex)</phrase>
                                       </p></item><item role="user-defined"><p role="item">
                                          <phrase>user-defined union types</phrase>
                                          <phrase role="kind"> (user-defined)</phrase>
                                       </p></item><item role="user-defined"><p role="last">
                                          <phrase>user-defined enumeration types</phrase>
                                          <phrase role="kind"> (user-defined)</phrase>
                                       </p></item></ulist></item></ulist></item><item role="abstract"><p role="last">
                              <phrase>complex types</phrase>
                              <phrase role="kind"> (complex)</phrase>
                           </p><ulist><item role="built-in-complex"><p role="first">
                                    <phrase>untyped</phrase>
                                    <phrase role="kind"> (built-in complex)</phrase>
                                 </p></item><item role="user-defined"><p role="last">
                                    <phrase>user-defined complex types</phrase>
                                    <phrase role="kind"> (user-defined)</phrase>
                                 </p></item></ulist></item></ulist></item></ulist></item></ulist></item></ulist>

<ulist role="type-hierarchy type-colors"><item><p role="root"><phrase>Supertype</phrase></p><ulist><item><p><phrase>subtype</phrase></p></item></ulist></item></ulist>
<ulist role="type-legend type-colors"><item role="abstract"><p>
         <phrase>Abstract types</phrase>
         <phrase role="kind"> (abstract)</phrase>
      </p></item><item role="built-in-atomic"><p>
         <phrase>Built-in atomic types</phrase>
         <phrase role="kind"> (built-in atomic)</phrase>
      </p></item><item role="built-in-complex"><p>
         <phrase>Built-in complex types</phrase>
         <phrase role="kind"> (built-in complex)</phrase>
      </p></item><item role="built-in-list"><p>
         <phrase>Built-in list types</phrase>
         <phrase role="kind"> (built-in list)</phrase>
      </p></item><item role="user-defined"><p>
         <phrase>User-defined types</phrase>
         <phrase role="kind"> (user-defined)</phrase>
      </p></item></ulist>
</p></div3><div3 id="atomic-type-hierarchy"><head>Atomic Type Hierarchy</head><p id="hier_anyAtomicType">The final diagram shows all of the atomic types, including the primitive simple types and the
built-in types derived from the primitive simple types. 
This includes all the built-in datatypes defined in <bibref ref="xmlschema-2"/>.</p><p>Atomic types are both item types and schema types, so the root type <code nobreak="false">xs:anyAtomicType</code> may be found
      in both the previous diagrams.</p><p role="type-hierarchy-figure">
<ulist role="type-hierarchy type-colors"><item role="abstract primitive special root"><p role="root" id="th_anyAtomicType">
         <phrase>anyAtomicType</phrase>
      </p><ulist><item role="primitive"><p role="first">
               <phrase>anyURI</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>base64Binary</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>boolean</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>date</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>dateTime</phrase>
            </p><ulist><item role="atomic"><p role="first">
                     <phrase>dateTimeStamp</phrase>
                  </p></item></ulist></item><item role="primitive"><p role="item">
               <phrase>decimal</phrase>
            </p><ulist><item role="built-in-atomic"><p role="first">
                     <phrase>integer</phrase>
                  </p><ulist><item role="built-in-atomic"><p role="first">
                           <phrase>long</phrase>
                        </p><ulist><item role="built-in-atomic"><p role="first">
                                 <phrase>int</phrase>
                              </p><ulist><item role="built-in-atomic"><p role="first">
                                       <phrase>short</phrase>
                                    </p><ulist><item role="built-in-atomic"><p role="first">
                                             <phrase>byte</phrase>
                                          </p></item></ulist></item></ulist></item></ulist></item><item role="built-in-atomic"><p role="item">
                           <phrase>nonNegativeInteger</phrase>
                        </p><ulist><item role="built-in-atomic"><p role="first">
                                 <phrase>positiveInteger</phrase>
                              </p></item><item role="built-in-atomic"><p role="last">
                                 <phrase>unsignedLong</phrase>
                              </p><ulist><item role="built-in-atomic"><p role="first">
                                       <phrase>unsignedInt</phrase>
                                    </p><ulist><item role="built-in-atomic"><p role="first">
                                             <phrase>unsignedShort</phrase>
                                          </p><ulist><item role="built-in-atomic"><p role="first">
                                                   <phrase>unsignedByte</phrase>
                                                </p></item></ulist></item></ulist></item></ulist></item></ulist></item><item role="built-in-atomic"><p role="last">
                           <phrase>nonPositiveInteger</phrase>
                        </p><ulist><item role="built-in-atomic"><p role="first">
                                 <phrase>negativeInteger</phrase>
                              </p></item></ulist></item></ulist></item></ulist></item><item role="primitive"><p role="item">
               <phrase>double</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>duration</phrase>
            </p><ulist><item role="built-in-atomic"><p role="first">
                     <phrase>dayTimeDuration</phrase>
                  </p></item><item role="built-in-atomic"><p role="last">
                     <phrase>yearMonthDuration</phrase>
                  </p></item></ulist></item><item role="primitive"><p role="item">
               <phrase>float</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>gDay</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>gMonth</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>gMonthDay</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>gYear</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>gYearMonth</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>hexBinary</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>NOTATION</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>QName</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>string</phrase>
            </p><ulist><item role="built-in-atomic"><p role="first">
                     <phrase>normalizedString</phrase>
                  </p><ulist><item role="built-in-atomic"><p role="first">
                           <phrase>token</phrase>
                        </p><ulist><item role="built-in-atomic"><p role="last">
                                 <phrase>NMTOKEN</phrase>
                              </p></item><item role="built-in-atomic"><p role="item">
                                 <phrase>Name</phrase>
                              </p><ulist><item role="built-in-atomic"><p role="first">
                                       <phrase>NCName</phrase>
                                    </p><ulist><item role="built-in-atomic"><p role="first">
                                             <phrase>ENTITY</phrase>
                                          </p></item><item role="built-in-atomic"><p role="item">
                                             <phrase>ID</phrase>
                                          </p></item><item role="built-in-atomic"><p role="last">
                                             <phrase>IDREF</phrase>
                                          </p></item></ulist></item></ulist></item><item role="built-in-atomic"><p role="first">
                                 <phrase>language</phrase>
                              </p></item></ulist></item></ulist></item></ulist></item><item role="primitive"><p role="item">
               <phrase>time</phrase>
            </p></item><item role="primitive"><p role="last">
               <phrase>untypedAtomic</phrase>
            </p></item></ulist></item></ulist>

<ulist role="type-hierarchy type-colors"><item><p role="root"><phrase>Supertype</phrase></p><ulist><item><p><phrase>subtype</phrase></p></item></ulist></item></ulist>
<ulist role="type-legend type-colors"><item role="built-in-atomic"><p><phrase>Built-in atomic types</phrase></p></item></ulist>
</p></div3></div2><div2 id="terminology"><head>Terminology</head><changes><change issue="1337" PR="1361" date="2024-08-02">
                  The term <term>atomic value</term> has been replaced by <term>atomic item</term>.
               </change></changes><p>The terminology used to describe the functions and operators on types defined in <bibref ref="xmlschema-2"/> is defined in the body of this specification. The terms defined
            in this section are used in building those definitions.</p><note><p>Following in the tradition of <bibref ref="xmlschema-2"/>, the terms <term>type</term>
            and <term>datatype</term> are used interchangeably.</p></note><div3 id="atomic-terminology"><head>Atomic items</head><p>The following definitions are adopted from <bibref ref="xpath-datamodel-40"/>.</p><ulist><item><p><termdef id="dt-atomic-item" term="atomic item">An
               <term>atomic item</term> is a pair (<var>T</var>, <var>D</var>) where <var>T</var> 
                (the <termref def="dt-type-annotation"/>)
                 is an atomic type, and <var>D</var> (the <termref def="dt-datum"/>)
                 is a point in the value space of <var>T</var>.</termdef></p></item><item><p><termdef id="dt-primitive-type" term="primitive type">A <term>primitive type</term> 
                is one of the 19 <term>primitive atomic</term> types defined in
                <xspecref spec="XS2" ref="built-in-primitive-datatypes"/>
                of <bibref ref="xmlschema-2"/>, or the type <code nobreak="false">xs:untypedAtomic</code>
                defined in <bibref ref="xpath-datamodel-40"/>.</termdef></p></item><item><p><termdef id="dt-datum" term="datum">The <term>datum</term> of an <termref def="dt-atomic-item"/>
               is a point in the value space of its type, which is also a point in the value space of
               the primitive type from which that type is derived.</termdef> There are 20 primitive atomic types (19 defined
               in XSD, plus <code nobreak="false">xs:untypedAtomic</code>), and these have non-overlapping value spaces, so each
               datum belongs to exactly one primitive atomic type.</p></item><item><p diff="chg" at="2022-11-05"><termdef id="dt-type-annotation" term="type annotation">The 
                <term>type annotation</term> of an atomic item
               is the most specific atomic type that it is an instance of 
                (it is also an instance of every type from which that
               type is derived).</termdef></p></item></ulist><note diff="chg" at="2022-11-05"><p>The term <term>value space</term> is defined in <bibref ref="xmlschema11-2"/>
      as a set of <emph>values</emph>. The term <term>datum</term> is used here in preference to <emph>value</emph>,
      because <term>value</term> has a different meaning in this data model.</p></note></div3><div3 id="character-terminology"><head>Strings, characters, and codepoints</head><p>This document uses the terms <code nobreak="false">string</code>, <code nobreak="false">character</code>, and <code nobreak="false">codepoint</code>
               with meanings that are normatively defined in <bibref ref="xpath-datamodel-40"/>, and which are paraphrased here
                  for ease of reference:</p><p><termdef id="character" term="character">A <term>character</term> is an instance of the 
                  <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XML" ref="NT-Char" xlink:type="simple">Char</xnt> production of <bibref ref="xml"/>.</termdef></p><note><p>This
               definition excludes Unicode characters in the surrogate blocks as well as <char>U+FFFE</char> and <char>U+FFFF</char>, while
                  including characters with codepoints greater than <char>U+FFFF</char> which some programming languages treat
               as two characters. The valid characters are defined by their codepoints, and include some
               whose codepoints have not been assigned by the Unicode consortium to any character.</p></note><p><termdef id="string" term="string">A <term>string</term> is a sequence of zero or more 
                  <termref def="character">characters</termref>, or equivalently,
               a value in the value space of the <code nobreak="false">xs:string</code> datatype.</termdef></p><p><termdef id="codepoint" term="codepoint">A <term>codepoint</term> is an integer
               assigned to a <termref def="character">character</termref> by the Unicode consortium, 
               or reserved for future assignment to a character.</termdef>
               </p><note><p>The set of codepoints is thus wider than the set of characters.</p><p>This specification spells “codepoint” as one word; the Unicode specification spells
                     it as “code point”.
                  Equivalent terms found in other specifications are
                  “character number” or “code position”. See <bibref ref="charmod"/></p></note><p>Because these terms appear so frequently, they are hyperlinked to the definition only when there
                  is a particular desire to draw the reader’s attention to the definition; the absence of a hyperlink
                  does not mean that the term is being used in some other sense.</p><p>It is <termref def="implementation-defined"/> which version of <bibref ref="Unicode"/> is supported, but it is recommended that the most recent version of Unicode be used.</p><p>This specification adopts the Unicode notation <code nobreak="false">U+xxxx</code> to refer to a codepoint
               by its hexadecimal value (always four to six hexadecimal digits). This is followed where appropriate
               by the official Unicode character name and its graphical representation: for example <char>U+20AC</char>.</p><p diff="chg" at="2023-01-17">Unless explicitly stated, the functions in this document do not ensure that any 
                  returned <code nobreak="false">xs:string</code> values are normalized in the sense of <bibref ref="charmod"/>.</p><note><p>In functions that involve character counting such
                     as <function>fn:substring</function>, <function>fn:string-length</function> and
                     <function>fn:translate</function>, what is counted is the number of XML <termref def="character">characters</termref>
                     in the string (or equivalently, the number of Unicode codepoints). Some
                     implementations may represent a codepoint above <char>U+FFFF</char> using two 16-bit
                     values known as a surrogate pair. A surrogate pair counts as one character, not two.</p></note><p>Wherever encoding names (such as <code nobreak="false">UTF-8</code> and <code nobreak="false">UTF-16</code>) are used in this specification,
               they are compared without regard to case: the strings <code nobreak="false">"UTF-8"</code> and <code nobreak="false">"utf-8"</code> both
               refer to the same encoding.</p></div3><div3 id="namespace-terminology"><head>Namespaces and URIs</head><p>This document uses the phrase “namespace URI” to identify the concept identified
                  in <bibref ref="xml-names"/> as “namespace name”, and the phrase “local name”
                  to identify the concept identified in <bibref ref="xml-names"/> as “local part”.</p><p>It also uses the term <quote>expanded-QName</quote> defined below.</p><p><termdef id="expanded-name" term="expanded-QName"> An <term>expanded-QName</term> 
                  is a value in the value space of the <code nobreak="false">xs:QName</code> datatype as defined in the XDM data model 
                  (see <bibref ref="xpath-datamodel-40"/>): that is, a triple containing namespace prefix (optional), namespace URI (optional), 
                  and local name. Two expanded QNames are equal if the namespace URIs are the same (or both absent) 
                  and the local names are the same. The prefix plays no part in the comparison, but is used only 
                  if the expanded QName needs to be converted back to a string.</termdef></p><p>The term URI is used as follows:</p><p><termdef id="dt-uri" term="URI">Within this specification, the term <term>URI</term> refers to Universal Resource Identifiers as
                  defined in <bibref ref="rfc3986"/> and extended in <bibref ref="rfc3987"/> with a new name <term>IRI</term>.  The term <term>URI   
                     Reference</term>, unless otherwise stated, refers to a string in the lexical space of the <code nobreak="false">xs:anyURI</code> datatype 
                  as defined in <bibref ref="xmlschema-2"/>.</termdef></p><note><p>
                     This means, in practice, that where this 
                     specification requires a “URI Reference”, an IRI as defined in <bibref ref="rfc3987"/> will be 
                     accepted, provided that other relevant specifications also permit an IRI. The term URI has been 
                     retained in preference to IRI to avoid introducing new names for concepts such as “Base URI” that 
                     are defined or referenced across the whole family of XML specifications.  Note also that the 
                     definition of <code nobreak="false">xs:anyURI</code> is a wider definition than the definition in <bibref ref="rfc3987"/>; 
                     for example it does not require non-ASCII characters to be escaped.
                  </p></note></div3><div3 id="conformance-terminology"><head>Conformance terminology</head><p>In this specification:</p><ulist><item><p>The auxiliary verb <rfc2119>must</rfc2119>, when rendered in small capitals, indicates a precondition for conformance.</p><ulist><item><p>When the sentence relates to an implementation of a function (for example "All implementations <rfc2119>must</rfc2119> 
                        recognize URIs of the form ...") then an implementation is not conformant unless it behaves as stated.
                     </p></item><item><p>When the sentence relates to the result of a function (for example "The result <rfc2119>must</rfc2119> have the same type as 
                        <code nobreak="false">$arg</code>") then the implementation is not conformant unless it delivers a result as stated.
                     </p></item><item><p>When the sentence relates to the arguments to a function (for example "The value of <code nobreak="false">$arg</code> <rfc2119>must</rfc2119> 
                        be a valid regular expression") then the implementation is not conformant unless it enforces the condition by raising a dynamic error 
                        whenever the condition is not satisfied. 
                     </p></item></ulist></item><item><p>The auxiliary verb <rfc2119>may</rfc2119>, when rendered in small capitals, indicates optional or discretionary behavior. 
                     The statement “An implementation <rfc2119>may</rfc2119> do X” implies that it is implementation-dependent whether or not it does X.</p></item><item><p>The auxiliary verb <rfc2119>should</rfc2119>, when rendered in small capitals, indicates desirable or recommended behavior. 
                     The statement “An implementation <rfc2119>should</rfc2119> do X” implies that it is desirable to do X, but implementations may choose
                     to do otherwise if this is judged appropriate.</p></item></ulist><p><termdef id="implementation-defined" term="implementation-defined">Where behavior is described as 
               <term>implementation-defined</term>, variations between processors are permitted, but a 
                  conformant implementation <rfc2119>must</rfc2119> document the choices it has made.</termdef></p><p><termdef id="implementation-dependent" term="implementation-dependent">Where behavior is described as 
                  <term>implementation-dependent</term>, variations between processors are permitted, and  
                  conformant implementations are not required to document the choices they have made.</termdef></p><note><p>Where this specification states that something is implementation-defined or implementation-dependent, it is
               open to host languages to place further constraints on the behavior.</p></note></div3><div3 id="properties-of-functions"><head>Properties of functions</head><p>This section is concerned with the question of whether two calls on a function, with the same arguments, may
               produce different results.</p><p diff="add" at="2023-03-12">In this section the term <term>function</term>, unless otherwise specified,
               applies equally to <xtermref spec="XP40" ref="dt-function-definition">function definitions</xtermref>
               (which can be the target of a static function call) and <xtermref spec="DM40" ref="dt-function-item">function items</xtermref>
               (which can be the target of a dynamic function call).</p><p><termdef id="execution-scope" term="execution scope">An <term>execution scope</term> is a sequence of
                  calls to the function library during which certain aspects of the state are required to remain invariant.
                  For example, two calls to <function>fn:current-dateTime</function> within the same execution scope will return the same result.
                  The execution scope is defined by the host language that invokes the function library.</termdef>
                  In XSLT, for example, any two function calls executed during
                  the same transformation are in the same execution scope (except that static expressions, such as those used in
                  <code nobreak="false">use-when</code> attributes, are in a separate execution scope).
                  </p><p>The following definition explains more precisely what it means for two function calls to return the same result:</p><p><termdef id="dt-identical" term="identical" diff="chg" at="2023-05-25">Two values <code nobreak="false">$V1</code> and <code nobreak="false">$V2</code> are
                  defined to be <term>identical</term> if they contain the same number of items and the items are pairwise identical. Two items are identical
                  if and only if one of the following conditions applies:</termdef></p><olist><item><p>Both items are atomic items, of precisely the same type, and the values are equal as defined using the <code nobreak="false">eq</code> operator,
                     using the Unicode codepoint collation when comparing strings.</p></item><item><p>Both items are nodes, and represent the same node.</p></item><item><p>Both items are maps, both maps have the same number of entries, 
                     and for every entry <var>E1</var> in the first map there is an entry <var>E2</var> in the second map such 
                     that the keys of <var>E1</var> and <var>E2</var> are <termref def="dt-same-key">the same key</termref>, 
                     and the corresponding values <var>V1</var> and <var>V2</var> are <termref def="dt-identical"/>.</p></item><item><p>Both items are arrays, both arrays have the same number of members, and the members
                     are pairwise <termref def="dt-identical"/>.</p></item><item><p>Both items are function items, 
                     neither item is a map or array, and the two function items have the same function identity.
                  The concept of function identity is explained in <xspecref spec="DM40" ref="function-items"/>.</p></item></olist><p>Some functions produce results that depend not only on their explicit arguments, 
                  but also on the static and dynamic context.</p><p><termdef id="dt-context-dependent" term="context-dependent">A 
                  <phrase diff="chg" at="2023-03-12"><xtermref spec="XP40" ref="dt-function-definition">function definition</xtermref></phrase> 
                  may have  the property of being <term>context-dependent</term>: the result of such a
               function depends on the values of properties in the static and dynamic
               evaluation context <phrase diff="add" at="2023-03-12">of the caller</phrase>
                  as well as on the actual supplied arguments (if any). A function definition may
               be context-dependent for some arities in its arity range, and context-independent
               for others: for example <function>fn:name#0</function> is context-dependent
                  while <function>fn:name#1</function> is context-independent.</termdef></p><p><termdef id="dt-context-independent" term="context-independent">A 
                  <phrase diff="chg" at="2023-03-12"><xtermref spec="XP40" ref="dt-function-definition">function definition</xtermref></phrase> 
                  that is not <termref def="dt-context-dependent">context-dependent</termref> is called 
                  <term>context-independent</term>.</termdef></p><p diff="add" at="2023-03-12">The main categories of context-dependent functions are:</p><ulist diff="add" at="2023-03-12"><item><p>Functions that explicitly deliver the value of a component of the static or dynamic context,
                  for example <function>fn:static-base-uri</function>, <function>fn:default-collation</function>,
                  <function>fn:position</function>, or <function>fn:last</function>.</p></item><item><p>Functions with an optional parameter whose default value is taken from the static
                     or dynamic context of the caller, usually either the context value (for example, <function>fn:node-name</function>)
                     or the default collation (for example, <function>fn:index-of</function>).</p></item><item><p>Functions that use the static context of the caller to expand or disambiguate
                  the values of supplied arguments: for example <function>fn:doc</function> expands its first
                  argument using the static base URI of the caller, and <code nobreak="false">xs:QName</code> expands its first argument
                  using the in-scope namespaces of the caller.</p></item></ulist><p><termdef id="dt-focus-dependent" term="focus-dependent">A function is <term>focus-dependent</term>
                  if its result depends on the <xtermref ref="dt-focus" spec="XP40">focus</xtermref>
                  (that is, the context item, position, or size) 
                  <phrase diff="add" at="2023-03-12">of the caller</phrase>.</termdef></p><p><termdef id="dt-focus-independent" term="focus-dependent">A function that
                  is not <termref def="dt-focus-dependent">focus-dependent</termref> is called
                  <term>focus-independent</term>.</termdef></p><note diff="add" at="2023-03-12"><p>Some functions depend on aspects of the dynamic context that remain invariant
                  within an <termref def="execution-scope"/>, such as the implicit timezone.
                  Formally this is treated in the same way as any other context dependency, but
                  internally, the implementation may be able to take advantage of the fact that the
                  value is invariant.</p></note><note diff="add" at="2023-03-12"><p>User-defined functions in XQuery and XSLT may depend on the static context
                     of the function definition (for example, the in-scope namespaces) and also in a limited
                     way on the dynamic context (for example, the values of global variables).
                     However, the only way they can depend on the static or dynamic context
                     of the caller — which is what concerns us here — is by defining optional
                     parameters whose default values are context-dependent.</p></note><note diff="add" at="2023-09-05"><p>Because the focus is a specific part of the dynamic context, all 
                  <termref def="dt-focus-dependent">focus-dependent</termref> functions are also
                  <termref def="dt-context-dependent">context-dependent</termref>. A
                  <termref def="dt-context-dependent">context-dependent</termref> function, however,
                  may be either <termref def="dt-focus-dependent">focus-dependent</termref> or
                     <termref def="dt-focus-independent">focus-independent</termref>.</p></note><p>A <phrase diff="chg" at="2023-03-12">function definition</phrase> that is context-dependent 
                  can be used as <phrase diff="add" at="2023-03-12">the target of</phrase> a named
               function reference, can be partially applied, and can be found using <function>fn:function-lookup</function>. 
               The principle in such cases is that the static context used for the function evaluation
               is taken from the static context of the named function reference, partial function application, or the call
               on <function>fn:function-lookup</function>; and the dynamic context for the function evaluation is taken from the dynamic
               context of the evaluation of the named function reference, partial function application, or the call
               of <function>fn:function-lookup</function>. <phrase diff="add" at="2023-03-12">These constructs all deliver a 
                  <xtermref spec="DM40" ref="dt-function-item">function item</xtermref>
                  having a <term>captured context</term> based on the static and dynamic
                  context of the construct that created the function item. This captured context forms 
               part of the closure of the function item.</phrase></p><p>The result of a dynamic call to a function item never 
                  depends on the static or dynamic context of the dynamic function call, only (where relevant) 
                  on the captured context held within the function item itself.</p><p>The <function>fn:function-lookup</function> function is a special case because it is
               potentially dependent on everything in the static and dynamic context. This is because the static and dynamic
               context of the call to <function>fn:function-lookup</function> 
                  <phrase diff="chg" at="2023-03-12">form the captured context of the
               function item</phrase> that <function>fn:function-lookup</function> returns.</p><p><termdef id="dt-deterministic" term="deterministic">A function that is guaranteed to produce <termref def="dt-identical">identical</termref> results 
                  from repeated calls within a single <termref def="execution-scope">execution scope</termref>
               if the explicit and implicit arguments are identical is referred to as
               <term>deterministic</term>.</termdef></p><p><termdef id="dt-nondeterministic" term="nondeterministic">A function that is not
                  <termref def="dt-deterministic">deterministic</termref> is referred to as <term>nondeterministic</term>.</termdef></p><p>All functions defined in this specification are <termref def="dt-deterministic">deterministic</termref> unless otherwise stated.
               Exceptions include the following:</p><ulist><item><p><termdef id="dt-nondeterministic-wrt-ordering" term="nondeterministic with respect to ordering">Some 
                  functions (such as <function>fn:in-scope-prefixes</function>,
                  <function>fn:load-xquery-module</function>, and <function>fn:unordered</function>) produce result sequences 
                  or result maps in an
                  <termref def="implementation-defined">implementation-defined</termref> or 
                  <termref def="implementation-dependent">implementation-dependent</termref> order. 
                  In such cases two calls with the same arguments are not guaranteed to produce the results in the same order. These functions are
               said to be <term>nondeterministic with respect to ordering</term>.</termdef></p></item><item><p>Some functions (such as <function>fn:analyze-string</function>,
                  <function>fn:parse-xml</function>, <function>fn:parse-xml-fragment</function>, 
                  <function>fn:parse-html</function>, and <function>fn:json-to-xml</function>) 
                  construct a tree of nodes to
               represent their results. There is no guarantee that repeated calls with the same
               arguments will return the same identical node (in the sense of the <code nobreak="false">is</code>
               operator). However, if non-identical nodes are returned, their content will be the
               same in the sense of the <function>fn:deep-equal</function> function. Such a function is said 
               to be <term>nondeterministic with respect to node identity</term>.</p></item><item><p>Some functions (such as <function>fn:doc</function> and 
                  <function>fn:collection</function>) create new nodes by reading external
               documents. Such functions are guaranteed to be <termref def="dt-deterministic">deterministic</termref>
               by default (some such functions have an option <code nobreak="false">"stable":false()</code> that makes 
               them nondeterministic as a user option, and implementations <rfc2119>may</rfc2119>
               also provide configuration options to change the default).</p></item></ulist><p>Where the results of a function are described as being (to a greater or lesser
                  extent) <termref def="implementation-defined">implementation-defined</termref> or 
                  <termref def="implementation-dependent">implementation-dependent</termref>, this does not by
               itself remove the requirement that the results should be deterministic: that is, that
               repeated calls with the same explicit and implicit arguments <rfc2119>must</rfc2119> return
               identical results.</p><p><termdef id="dt-variadic" term="variadic">The function <function>fn:concat</function>
                  is defined to be variadic: it accepts any number of arguments. No other function
                  has this property.</termdef></p></div3></div2></div1><div1 id="sequence-functions"><head>Processing sequences</head><p>A <code nobreak="false">sequence</code> is an ordered collection of zero or more <code nobreak="false">items</code>.
                An <code nobreak="false">item</code> is a node, an atomic item, or a function, such as a map or an array. The terms
                <code nobreak="false">sequence</code> and <code nobreak="false">item</code> are defined formally in <bibref ref="xquery-40"/> and <bibref ref="xpath-40"/>. </p><div2 id="general-seq-funcs"><head>General functions on sequences</head><p>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.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:empty</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the argument is the empty sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:exists</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the argument is a non-empty sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:foot</code></td><td rowspan="1" colspan="1">Returns the last item in a sequence. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:head</code></td><td rowspan="1" colspan="1">Returns the first item in a sequence. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:identity</code></td><td rowspan="1" colspan="1">Returns its argument value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:insert-before</code></td><td rowspan="1" colspan="1">Returns a sequence constructed by inserting an item or a sequence of items at a given
            position within an existing sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:insert-separator</code></td><td rowspan="1" colspan="1">Inserts a separator between adjacent items in a sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:items-at</code></td><td rowspan="1" colspan="1">Returns a sequence containing the items from <code nobreak="false">$input</code>
            at positions defined by <code nobreak="false">$at</code>, in the order specified. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:remove</code></td><td rowspan="1" colspan="1">Returns a new sequence containing all the items of <code nobreak="false">$input</code> <phrase diff="chg" at="2023-01-17">except those
            at specified positions</phrase>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:replicate</code></td><td rowspan="1" colspan="1">Produces multiple copies of a sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:reverse</code></td><td rowspan="1" colspan="1">Reverses the order of items in a sequence. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:slice</code></td><td rowspan="1" colspan="1">Returns a sequence containing selected items from a supplied input sequence based on their position.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:subsequence</code></td><td rowspan="1" colspan="1">Returns the contiguous sequence of items in <code nobreak="false">$input</code>
            beginning at the position indicated by <code nobreak="false">$start</code> and
            continuing for the number of items indicated by <code nobreak="false">$length</code>. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:tail</code></td><td rowspan="1" colspan="1">Returns all but the first item in a sequence. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:trunk</code></td><td rowspan="1" colspan="1">Returns all but the last item in a sequence. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:unordered</code></td><td rowspan="1" colspan="1">Returns the items of <code nobreak="false">$input</code> in an <termref def="implementation-dependent">implementation-dependent</termref> order.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:void</code></td><td rowspan="1" colspan="1">Absorbs the argument.</td></tr></tbody></table><p>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 <code nobreak="false">$seq</code> is bound to the
                    sequence of line-item nodes in document order. The variables
                    <code nobreak="false">$item1</code>, <code nobreak="false">$item2</code>, etc. are bound to separate, individual
                    line-item nodes in the sequence.</p><div3 id="func-empty"><head>fn:empty</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the argument is the empty sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="empty" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$input</code> is the empty sequence, the function returns
               <code nobreak="false">true</code>; otherwise, the function returns <code nobreak="false">false</code>. </p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">count($input) eq 0</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">empty((1, 2, 3)[10])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">empty(remove(("hello", "world"), 1))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">empty([])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">empty({})</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">empty("")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td colspan="2" rowspan="1"><p>Assuming <code nobreak="false">$break</code> is an element with no children:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">
let $break := &lt;br/&gt;
return empty($break)
            </eg></td></tr><tr><td colspan="2" rowspan="1"><p>The result is <code nobreak="false">false</code>.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-exists"><head>fn:exists</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the argument is a non-empty sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="exists" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$input</code> is a non-empty sequence, the function returns
               <code nobreak="false">true</code>; otherwise, the function returns <code nobreak="false">false</code>. </p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">count($input) gt 0</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">exists(remove(("hello"), 1))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">exists(remove(("hello", "world"), 1))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">exists([])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">exists({})</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">exists("")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td colspan="2" rowspan="1"><p>Assuming <code nobreak="false">$break</code> is an element with no children:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">
let $break := &lt;br/&gt;
return exists($break)
            </eg></td></tr><tr><td colspan="2" rowspan="1"><p>The result is <code nobreak="false">true</code>.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-foot" diff="add" at="2022-11-16"><head>fn:foot</head><changes><change issue="97" PR="250" date="2022-12-07">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the last item in a sequence. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="foot" return-type="item()?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the value of the expression <code nobreak="false">$input[last()]</code></p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter($input, fn($item, $pos) { $pos eq count($input) })</eg></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$input</code> is the empty sequence, the empty sequence is returned. </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">foot(1 to 5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">5</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">foot(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-head"><head>fn:head</head><glist><gitem><label>Summary</label><def><p>Returns the first item in a sequence. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="head" return-type="item()?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the first item in <code nobreak="false">$input</code>; if <code nobreak="false">$input</code>
         is empty, it returns the empty sequence.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter($input, fn($item, $pos) { $pos eq 1 })</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">head(1 to 5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">head(("a", "b", "c"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">head(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">head([ 1, 2, 3 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 1, 2, 3 ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-identity" diff="add" at="A"><head>fn:identity</head><changes><change date="2022-09-20" issue="858" PR="1473">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns its argument value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="identity" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns <code nobreak="false">$input</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">$input</eg></def></gitem><gitem><label>Notes</label><def><note><p>The function is useful in contexts where a function must be supplied, but no processing is required.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">identity(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">identity(1 to 10)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2, 3, 4, 5, 6, 7, 8, 9, 10</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-xml('&lt;a/&gt;') ! (identity(/) is /)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p><p><emph>(If the argument is a node, the function returns the identical node, not a copy).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">identity(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-insert-before"><head>fn:insert-before</head><glist><gitem><label>Summary</label><def><p>Returns a sequence constructed by inserting an item or a sequence of items at a given
            position within an existing sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="insert-before" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="position" type="xs:integer"/><arg name="insert" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The value returned by the function consists of all items of <code nobreak="false">$input</code> whose
            1-based position is less than <code nobreak="false">$position</code>, followed by all items of
               <code nobreak="false">$insert</code>, followed by the remaining elements of <code nobreak="false">$input</code>, in
            that order. </p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter($input, fn($item, $pos) { $pos lt $position }),
$insert,
filter($input, fn($item, $pos) { $pos ge $position })</eg></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$input</code> is the empty sequence, <code nobreak="false">$insert</code> is returned. If
               <code nobreak="false">$insert</code> is the empty sequence, <code nobreak="false">$input</code> is returned.</p><p>If <code nobreak="false">$position</code> is less than one (1), the first position, the effective value
            of <code nobreak="false">$position</code> is one (1). If <code nobreak="false">$position</code> is greater than the
            number of items in <code nobreak="false">$input</code>, then the effective value of
               <code nobreak="false">$position</code> is equal to the number of items in <code nobreak="false">$input</code> plus
            1. </p><p>The value of <code nobreak="false">$input</code> is not affected by the sequence construction.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $abc := ("a", "b", "c")</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">insert-before($abc, 0, "z")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"z", "a", "b", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">insert-before($abc, 1, "z")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"z", "a", "b", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">insert-before($abc, 2, "z")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "z", "b", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">insert-before($abc, 3, "z")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b", "z", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">insert-before($abc, 4, "z")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b", "c", "z"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-insert-separator"><head>fn:insert-separator</head><changes><change issue="2 868 2327" PR="1504 2329" date="2022-09-27">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Inserts a separator between adjacent items in a sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="insert-separator" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="separator" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function inserts a separator between adjacent items in a sequence.
            The input is returned unchanged if <code nobreak="false">$separator</code> is the empty sequence
            or if <code nobreak="false">$input</code> contains less than two items.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">for-each($input, fn($item, $pos) {
  if ($pos gt 1) { $separator },
  $item
})</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">insert-separator(1 to 5, "|")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, "|", 2, "|" , 3, "|", 4, "|", 5</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">insert-separator((), "|")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">insert-separator("A", "|")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"A"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">insert-separator(1 to 3, ("⅓", "⅔"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, "⅓", "⅔", 2, "⅓", "⅔", 3</code></p></td></tr><tr><td colspan="2" rowspan="1"><p>Insert an empty <code nobreak="false">hr</code> element between adjacent paragraphs:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">insert-separator(./para, &lt;hr/&gt;)</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-items-at" diff="add" at="2022-11-16"><head>fn:items-at</head><changes><change issue="213" PR="419" date="2022-11-22">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a sequence containing the items from <code nobreak="false">$input</code>
            at positions defined by <code nobreak="false">$at</code>, in the order specified. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="items-at" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="at" type="xs:integer*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Returns the items in <code nobreak="false">$input</code> at the positions listed
         in <code nobreak="false">$at</code>, in order of the integers in the <code nobreak="false">$at</code> argument.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">for-each($at, fn($index) { subsequence($input, $index, 1) })</eg></def></gitem><gitem><label>Notes</label><def><note><p>In the simplest case where <code nobreak="false">$at</code> is a single integer,
         <code nobreak="false">fn:items-at($input, 3)</code> returns the same result as <code nobreak="false">$input[3]</code>.</p><p>Compared with a simple positional filter expression, the function is useful because:</p><olist><item><p>It can select items at multiple positions, and unlike <function>fn:subsequence</function>,
            these do not need to be contiguous.</p></item><item><p>The <code nobreak="false">$at</code> expression can depend on the focus.</p></item><item><p>The order of the returned items can differ from their order in the <code nobreak="false">$input</code> sequence.</p></item></olist><p>If any integer in <code nobreak="false">$at</code> is outside the range <code nobreak="false">1 to count($input)</code>, that integer
         is effectively ignored: no error occurs.</p><p>If either of the arguments is the empty sequence, the result is the empty sequence.</p><p>If <code nobreak="false">$at</code> contains duplicate integers, the result also contains duplicates. No de-duplication 
            occurs. If the input sequence contains nodes, these are not copied: instead, the result
            sequence contains multiple references to the same node.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">items-at(11 to 20, 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">14</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">items-at(11 to 20, 4 to 6)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">14, 15, 16</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">items-at(11 to 20, (7, 3))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">17, 13</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">items-at(11 to 20, index-of(("a", "b", "c"), "b"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">12</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">items-at(characters("quintessential"), (4, 8, 3))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"n", "s", "i"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">items-at(characters("quintessential"), (4, 8, 1, 1))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"n", "s", "q", "q"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">items-at((), 832)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">items-at((), ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-remove"><head>fn:remove</head><changes><change issue="294" PR="313" date="2023-01-24">The second argument can now be a sequence of integers.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a new sequence containing all the items of <code nobreak="false">$input</code> <phrase diff="chg" at="2023-01-17">except those
            at specified positions</phrase>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="remove" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="positions" type="xs:integer*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence consisting of all items of <code nobreak="false">$input</code> <phrase diff="chg" at="2023-01-17">whose
            1-based position is not equal to any of the integers in <code nobreak="false">$positions</code>. </phrase></p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter($input, fn($item, $pos) { not($pos = $positions) })</eg></def></gitem><gitem><label>Notes</label><def><note><p diff="chg" at="2023-01-17">Any integer in <code nobreak="false">$positions</code> that is less than 1 or greater than the number of items in
               <code nobreak="false">$input</code> is effectively ignored.</p><p>If <code nobreak="false">$input</code> is the empty sequence, the empty sequence is returned.</p><p diff="add" at="2023-01-17">If <code nobreak="false">$positions</code> is the empty sequence, the input sequence <code nobreak="false">$input</code> is returned unchanged.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $abc := ("a", "b", "c")</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">remove($abc, 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">remove($abc, 1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">remove($abc, 6)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">remove((), 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">remove($abc, 2 to 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">remove($abc, ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b", "c"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-replicate" diff="add" at="A"><head>fn:replicate</head><changes><change date="2022-10-04">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Produces multiple copies of a sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="replicate" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="count" type="xs:nonNegativeInteger"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the value of <code nobreak="false">(1 to $count) ! $input</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">for-each(1 to $count, fn($item, $pos) { $input })</eg></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$input</code> is the empty sequence, the empty sequence is returned.</p><p>The <code nobreak="false">$count</code> argument is declared as <code nobreak="false">xs:nonNegativeInteger</code>,
         which means that a type error occurs if it is called with a negative value.</p><p>If the input sequence contains nodes, these are not copied: instead, the result sequence contains
         multiple references to the same node. So, for example, <code nobreak="false">fn:count(fn:replicate(/, 6)|())</code>
         returns <code nobreak="false">1</code>, because the <function>fn:replicate</function> call creates duplicates, and the
            union operation eliminates them.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">replicate(0, 6)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0, 0, 0, 0, 0, 0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">replicate(("A", "B", "C"), 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"A", "B", "C", "A", "B", "C", "A", "B", "C"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">replicate((), 5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">replicate(("A", "B", "C"), 1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"A", "B", "C"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">replicate(("A", "B", "C"), 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-reverse"><head>fn:reverse</head><glist><gitem><label>Summary</label><def><p>Reverses the order of items in a sequence. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="reverse" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence containing the items in <code nobreak="false">$input</code> in reverse
            order.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">fold-left($input, (), fn($result, $item) { $item, $result })</eg></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$input</code> is the empty sequence, the empty sequence is returned. </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $abc := ("a", "b", "c")</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">reverse($abc)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"c", "b", "a"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">reverse(("hello"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"hello"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">reverse(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">reverse([ 1, 2, 3 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 1, 2, 3 ]</code></p><p><emph>(The input is a sequence containing a single item (the array)).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">reverse(([ 1, 2, 3 ], [ 4, 5, 6 ]))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 4, 5, 6 ], [ 1, 2, 3 ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-slice" diff="add" at="A"><head>fn:slice</head><changes><change>New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a sequence containing selected items from a supplied input sequence based on their position.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="slice" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="start" type="xs:integer?" default="0" note="default-on-empty"/><arg name="end" type="xs:integer?" default="0" note="default-on-empty"/><arg name="step" type="xs:integer?" default="0" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$input</code> is the empty sequence, the function returns the empty sequence.</p><p>Let <code nobreak="false">$S</code> be the first of the following that applies:</p><ulist><item><p>If <code nobreak="false">$start</code> is zero, then 1.</p></item><item><p>If <code nobreak="false">$start</code> is negative, then <code nobreak="false">fn:count($input) + $start + 1</code>.</p></item><item><p>Otherwise, <code nobreak="false">$start</code>.</p></item></ulist><p>Let <code nobreak="false">$E</code> be the first of the following that applies:</p><ulist><item><p>If <code nobreak="false">$end</code> is zero, then <code nobreak="false">fn:count($input)</code>.</p></item><item><p>If <code nobreak="false">$end</code> is negative, then <code nobreak="false">fn:count($input) + $end + 1</code>.</p></item><item><p>Otherwise, <code nobreak="false">$end</code>.</p></item></ulist><p>Let <code nobreak="false">$STEP</code> be the first of the following that applies:</p><ulist><item><p>If <code nobreak="false">$step</code> is zero, then:</p><ulist><item><p>If <code nobreak="false">$E ge $S</code>, then +1</p></item><item><p>Otherwise -1</p></item></ulist></item><item><p>Otherwise, <code nobreak="false">$step</code>.</p></item></ulist><p>If <code nobreak="false">$STEP</code> is negative, the function returns 
            <code nobreak="false">$input =&gt; fn:reverse() =&gt; fn:slice(-$S, -$E, -$STEP)</code>.</p><p>Otherwise the function returns the result of the expression:</p><eg xml:space="preserve">$input[position() ge $S and position() le $E and (position() - $S) mod $STEP eq 0]</eg><ednote><edtext>TBA: define formal equivalent.</edtext></ednote></def></gitem><gitem><label>Notes</label><def><note><p>The function is inspired by the slice operators in Javascript and Python, but it differs
         in detail to accommodate the tradition of 1-based addressing in XPath. The end position is
         inclusive rather than exclusive, so that in the simple case where <code nobreak="false">$start</code> and
            <code nobreak="false">$end</code> are positive and <code nobreak="false">$end &gt; $start</code>, 
            <code nobreak="false">fn:slice($in, $start, $end)</code>
         returns the same result as <code nobreak="false">$in[position() = $start to $end]</code>.</p><p>This function can be used to enhance the <code nobreak="false">RangeExpression</code>, defined
            in <xspecref spec="XP40" ref="id-range-expressions"/>, to construct a sequence
            of integers based on steps other than 1.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $in := ('a', 'b', 'c', 'd', 'e')</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 2, end := 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b", "c", "d"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b", "c", "d", "e"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, end := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 3, end := 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 4, end := 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"d", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 2, end := 5, step := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b", "d"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 5, end := 2, step := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"e", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 2, end := 5, step := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 5, end := 2, step := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b", "c", "d", "e"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := -1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"e"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"c", "d", "e"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, end := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b", "c", "d"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := 2, end := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b", "c", "d"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := -2, end := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"d", "c", "b"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := -4, end := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b", "c", "d"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := -2, end := -4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"d", "c", "b"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := -4, end := -2, step := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b", "d"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice($in, start := -2, end := -4, step := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"d", "b"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice(("a", "b", "c", "d"), 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b", "c", "d"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">slice((1 to 5), step := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 3, 5</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subsequence"><head>fn:subsequence</head><changes><change issue="895" PR="901" date="2023-12-16">The optional third argument can now be supplied as the empty sequence.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the contiguous sequence of items in <code nobreak="false">$input</code>
            beginning at the position indicated by <code nobreak="false">$start</code> and
            continuing for the number of items indicated by <code nobreak="false">$length</code>. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="subsequence" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="start" type="xs:double"/><arg name="length" type="xs:double?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If the third argument is the empty sequence, the function returns:</p><eg xml:space="preserve">$input[round($start) le position()]</eg><p>Otherwise, the function returns:</p><eg xml:space="preserve">$input[round($start) le position() and
       position() lt round($start) + round($length)]</eg></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter(
  $input,
  if (empty($length)) then (
    fn($item, $pos) { round($start) le $pos }
  ) else (
    fn($item, $pos) { round($start) le $pos and $pos lt round($start) + round($length) }
  )
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>The first item of a sequence is located at position 1, not position 0.</p><p>If <code nobreak="false">$input</code> is the empty sequence, the empty sequence is returned.</p><p>In the two-argument case, the function returns a sequence comprising those items of 
            <code nobreak="false">$input</code> whose 1-based position  
            is greater than or equal to <code nobreak="false">$start</code> (rounded to an integer). 
            No error occurs if <code nobreak="false">$start</code> is zero or negative.</p><p>In the three-argument case, The function returns a sequence comprising those items of 
            <code nobreak="false">$input</code> whose 1-based position  
            is greater than or equal to <code nobreak="false">$start</code> (rounded to an integer), and 
            less than the sum of <code nobreak="false">$start</code> and <code nobreak="false">$length</code> (both rounded to integers). 
            No error occurs if <code nobreak="false">$start</code> is zero or negative, or if <code nobreak="false">$start</code> 
            plus <code nobreak="false">$length</code> exceeds the number of items in the sequence, or if 
            <code nobreak="false">$length</code> is negative.</p><p>As a consequence of the general rules, if <code nobreak="false">$start</code> is
               <code nobreak="false">-INF</code> and <code nobreak="false">$length</code> is <code nobreak="false">+INF</code>, then
               <code nobreak="false">fn:round($start) + fn:round($length)</code> is <code nobreak="false">NaN</code>; since
               <code nobreak="false">position() lt NaN</code> always returns <code nobreak="false">false</code>, the result is the empty sequence.</p><p>The reason the function accepts arguments of type <code nobreak="false">xs:double</code> is that many
            computations on untyped data return an <code nobreak="false">xs:double</code> result; and the reason for
            the rounding rules is to compensate for any imprecision in these floating-point
            computations.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $seq := ("item1", "item2", "item3", "item4", "item5")</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">subsequence($seq, 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"item4", "item5"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">subsequence($seq, 3, 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"item3", "item4"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-tail"><head>fn:tail</head><glist><gitem><label>Summary</label><def><p>Returns all but the first item in a sequence. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="tail" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function all items in <code nobreak="false">$input</code> except the first, retaining order.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter($input, fn($item, $pos) { $pos gt 1 })</eg></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$input</code> is the empty sequence, or a sequence containing a single item, then
            the empty sequence is returned. </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">tail(1 to 5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2, 3, 4, 5</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">tail(("a", "b", "c"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b", "c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">tail("a")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">tail(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">tail([ 1, 2, 3 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-trunk" diff="add" at="2022-11-16"><head>fn:trunk</head><changes><change issue="97" PR="250" date="2022-12-07">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns all but the last item in a sequence. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="trunk" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns all items in <code nobreak="false">$input</code> except the last, retaining order.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter($input, fn($item, $pos) { $pos ne count($input) })</eg></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$input</code> is the empty sequence, or a sequence containing a single item, then
            the empty sequence is returned. </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">trunk(1 to 5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2, 3, 4</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">trunk(("a", "b", "c"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">trunk("a")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">trunk(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">trunk([ 1, 2, 3 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-unordered"><head>fn:unordered</head><glist><gitem><label>Summary</label><def><p>Returns the items of <code nobreak="false">$input</code> in an <termref def="implementation-dependent">implementation-dependent</termref> order.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="unordered" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic-wrt-ordering">nondeterministic-wrt-ordering</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the items of <code nobreak="false">$input</code> in an <termref def="implementation-dependent">implementation-dependent</termref> order.</p></def></gitem><gitem><label>Notes</label><def><note><p>Query optimizers may be able to do a better job if the order of the output sequence is
            not specified. For example, when retrieving prices from a purchase order, if an index
            exists on prices, it may be more efficient to return the prices in index order rather
            than in document order.</p><p>This function does not guarantee that the resulting sequence will be in an order
            different from the input sequence. Many times the two sequences will be identical. </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">unordered((1, 2, 3, 4, 5))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">(1, 2, 3, 4, 5)</code></p><p>(or some permutation thereof)</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-void"><head>fn:void</head><changes><change issue="1029" PR="1032" date="2025-02-25">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Absorbs the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="void" return-type="empty-sequence()" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function absorbs the supplied <code nobreak="false">$input</code> argument and
            returns the empty sequence.</p></def></gitem><gitem><label>Notes</label><def><note><p>The function can be used to discard unneeded output of expressions
            (functions, third-party libraries, etc.).</p><p>It can also be used to discard results during development.</p><p>It is <termref def="implementation-dependent">implementation-dependent</termref>
            whether the supplied argument is evaluated or ignored. An implementation may decide to
            evaluate <termref def="dt-nondeterministic">nondeterministic</termref> expressions and
            ignore deterministic ones.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">void(1 to 1000000)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">for $f in (identity#1, void#1) return $f(123)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">123</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $mapping := () 
return for-each(1 to 10, $mapping otherwise void#0)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg><p><emph>(Indicates that if no mapping is supplied, all items are dropped.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="comparing-sequences"><head>Comparison functions</head><p>The functions in this section perform comparisons between the items in one or more
            sequences.</p><p>Many of these functions require atomic items to be compared for equality.</p><p><termdef id="dt-contextually-equal" term="contextually equal">Two atomic items
            <var>A</var> and <var>B</var> are said to be <term>contextually equal</term>
            if the function call <code nobreak="false">fn:compare(<var>A</var>, <var>B</var>)</code>
            returns zero when evaluated with a specified or context-determined collation
            and implicit timezone.</termdef> If two values are not contextually equal,
            they are considered to be <term>contextually unequal</term>, even in the case when comparing
            them using <function>fn:compare</function> raises an error.</p><note><p>Except where explicitly stated otherwise, an appeal to 
            <termref def="dt-contextually-equal">contextual equality</termref> implies
            that <code nobreak="false">NaN</code> is treated as equal to <code nobreak="false">NaN</code>.</p></note><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:atomic-equal</code></td><td rowspan="1" colspan="1">Determines whether two atomic items are equal, under the rules used for comparing keys in a map.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:compare</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">-1</code>, <code nobreak="false">0</code>, or <code nobreak="false">1</code>, depending on whether
            the first value is less than, equal to, or greater than the second value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:contains-subsequence</code></td><td rowspan="1" colspan="1">Determines whether one sequence contains another as a contiguous subsequence, using a supplied callback function to compare items.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:deep-equal</code></td><td rowspan="1" colspan="1"> 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<phrase>,
               or maps with matching entries, or arrays with matching members.</phrase></td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:distinct-values</code></td><td rowspan="1" colspan="1">Returns the values that appear in a sequence, with duplicates eliminated.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:duplicate-values</code></td><td rowspan="1" colspan="1">Returns the values that appear in a sequence more than once.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:ends-with-subsequence</code></td><td rowspan="1" colspan="1">Determines whether one sequence ends with another, using a supplied callback function to compare items.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:index-of</code></td><td rowspan="1" colspan="1">Returns a sequence of positive integers giving the positions within the sequence
               <code nobreak="false">$input</code> of items that are <termref def="dt-contextually-equal"/> 
            to <code nobreak="false">$target</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:starts-with-subsequence</code></td><td rowspan="1" colspan="1">Determines whether one sequence starts with another, using a supplied callback function to compare items.</td></tr></tbody></table><div3 id="func-atomic-equal"><head>fn:atomic-equal</head><changes><change issue="221" PR="319" date="2023-02-01">New in 4.0. The function replaces the internal <code nobreak="false">op:same-key</code>
         function in 3.1</change><change issue="2139" PR="2168" date="2025-08-19">Atomic items of types <code nobreak="false">xs:hexBinary</code> 
            and <code nobreak="false">xs:base64Binary</code> are now mutually comparable. In rare cases, where an
            application uses both types and assumes they are distinct, this can represent a backwards
            incompatibility.</change></changes><glist><gitem><label>Summary</label><def><p>Determines whether two atomic items are equal, under the rules used for comparing keys in a map.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="atomic-equal" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value1" type="xs:anyAtomicType"/><arg name="value2" type="xs:anyAtomicType"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>fn:atomic-equal</function> is used to compare two atomic items for equality. This function
         has the following properties (which do not all apply to the <code nobreak="false">eq</code> operator):</p><ulist><item><p>Any two atomic items can be compared, regardless of their type.</p></item><item><p>No dynamic error is ever raised (the result is either <code nobreak="false">true</code> or <code nobreak="false">false</code>).</p></item><item><p>The result of the comparison never depends on the static or dynamic context.</p></item><item><p>Every value (including <code nobreak="false">NaN</code>) is equal to itself.</p></item><item><p>The comparison is symmetric: if <var>A</var> equals <var>B</var>, then <var>B</var> equals <var>A</var>.</p></item><item><p>The comparison is transitive: if <var>A</var> equals <var>B</var> and <var>B</var> equals <var>C</var>,
               then <var>A</var> equals <var>C</var>.</p></item></ulist><p>The function returns <code nobreak="false">true</code> if and only if one of the following conditions is true:</p><olist><item><p>All of the following conditions are true:</p><olist><item><p><code nobreak="false">$value1</code> is an instance of <code nobreak="false">xs:string</code>, <code nobreak="false">xs:anyURI</code>, or <code nobreak="false">xs:untypedAtomic</code></p></item><item><p><code nobreak="false">$value2</code> is an instance of <code nobreak="false">xs:string</code>, <code nobreak="false">xs:anyURI</code>, or <code nobreak="false">xs:untypedAtomic</code></p></item><item><p>
                        <code nobreak="false">fn:codepoint-equal($value1, $value2)</code>
                     </p></item></olist><note><p>Strings are compared without any dependency on collations.</p></note></item><item><p>All of the following conditions are true:</p><olist><item><p><code nobreak="false">$value1</code> is an instance of <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:double</code>, or <code nobreak="false">xs:float</code></p></item><item><p><code nobreak="false">$value2</code> is an instance of <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:double</code>, or <code nobreak="false">xs:float</code></p></item><item><p><code nobreak="false">fn:compare($value1, $value2)</code> returns zero.</p><note><p><code nobreak="false">NaN</code> is equal to <code nobreak="false">NaN</code>, <code nobreak="false">INF</code>
                     is equal to <code nobreak="false">INF</code>, <code nobreak="false">-INF</code> is equal to <code nobreak="false">-INF</code>,
                     positive zero equals negative zero. This applies both to <code nobreak="false">xs:double</code>
                     amd <code nobreak="false">xs:float</code> values, including comparisons across these two types.</p><p>Ordinary values (numeric values other than the special values mentioned above)
                           are compared according to their mathematical magnitude. 
                           Every instance of <code nobreak="false">xs:double</code>, <code nobreak="false">xs:float</code>, and <code nobreak="false">xs:decimal</code> can be represented
                              exactly as a decimal number provided enough digits are available both before and after the decimal point.
                              This comparison is therefore transitive.</p></note></item><item><p>All of the following conditions are true:</p><olist><item><p>One of the following conditions is true:</p><olist><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:date</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:time</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:dateTime</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:gYear</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:gYearMonth</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:gMonth</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:gMonthDay</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:gDay</code>.</p></item></olist></item><item><p>One of the following conditions is true:</p><olist><item><p>Both <code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> have a timezone</p></item><item><p>Neither <code nobreak="false">$value1</code> nor <code nobreak="false">$value2</code> has a timezone</p></item></olist></item><item><p>
                        <code nobreak="false">fn:compare($value1, $value2)</code> returns zero.
                     </p></item></olist><note><p>Values having a timezone are never equal to values without one. The implicit timezone is not used.</p></note></item><item><p>All of the following conditions are true:</p><olist><item><p><code nobreak="false">$value1</code> is an instance of <code nobreak="false">xs:hexBinary</code> or <code nobreak="false">xs:base64Binary</code></p></item><item><p><code nobreak="false">$value2</code> is an instance of <code nobreak="false">xs:hexBinary</code> or <code nobreak="false">xs:base64Binary</code></p></item><item><p><code nobreak="false">fn:compare($value1, $value2)</code> returns zero.</p></item></olist></item><item><p>All of the following conditions are true:</p><olist><item><p>One of the following conditions is true:</p><olist><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:boolean</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:QName</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:NOTATION</code>.</p></item><item><p><code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are both instances of <code nobreak="false">xs:duration</code>.</p></item></olist></item><item><p>
                        <code nobreak="false">fn:compare($value1, $value2)</code> returns zero.
                     </p></item></olist></item></olist></item></olist></def></gitem><gitem><label>Notes</label><def><note><p>The internal function <code role="example" nobreak="false">op:same-key</code> was introduced in an earlier version of this specification
            for comparing keys within a map.
            In this version of the specification, the functionality is unchanged, but the function is exposed so that it
            is available directly to applications.</p><p>The function is used to assess whether two atomic
            items are considered to be duplicates when used as keys in a map. A map cannot
            contain two separate entries whose keys are <term>the same</term> as defined by this function. 
            The function is also used when matching keys in functions such as <function>map:get</function>
            and <function>map:remove</function>.</p><p>The rules for comparing keys in a map are chosen to ensure that the comparison is:</p><ulist><item><p><term>Context-free</term>: there is no dependency on the static or dynamic context</p></item><item><p><term>Error-free</term>: any two atomic items can be compared, and the result is either <code nobreak="false">true</code> or <code nobreak="false">false</code>, never an error</p></item><item><p><term>Transitive</term>: if <var>A</var> is the same key as <var>B</var>, and <var>B</var> is the same key as <var>C</var>, 
               then <var>A</var> is the same key as <var>C</var>.</p></item></ulist><p>Two atomic items may be distinguishable even though they are equal under this comparison. For example: they may have
         different type annotations; dates and times may have different timezones; <code nobreak="false">xs:QName</code> values may have different
         prefixes.</p><p>Unlike previous versions of this specification, <code nobreak="false">xs:hexBinary</code> and
         <code nobreak="false">xs:base64Binary</code> values are mutually comparable. This decision affects backwards
         compatibility: it is no longer possible to construct certain maps that
         could be validly constructed using earlier versions of the specification. This may also cause problems
         passing data from a 3.1 processor to a 4.0 processor.</p><p>As always, any algorithm that delivers the right result is acceptable. For example, when testing whether an <code nobreak="false">xs:double</code>
         value <var>D</var> is the same key as an <code nobreak="false">xs:decimal</code> value that has <var>N</var> significant digits, it is not
         necessary to know all the digits in the decimal expansion of <var>D</var> to establish the result: computing the first <var>N+1</var> 
            significant digits (or indeed, simply knowing that there are more than <var>N</var> significant digits) is sufficient.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal("a", "a")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal("a", "A")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal("a", xs:untypedAtomic("a"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">atomic-equal(
  "https://www.w3.org/",
  xs:anyURI("https://www.w3.org/")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(3, 3)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(3, 3e0)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(3.1, 3.1e0)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(xs:double('NaN'), xs:float('NaN'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(12, "12")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(xs:time('16:00:00Z'), xs:time('17:00:00+01:00'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(xs:time('16:00:00Z'), xs:time('16:00:00'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(xs:duration('PT1H'), xs:duration('PT60M'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(xs:duration('PT0S'), xs:duration('P0Y'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(xs:duration('P30D'), xs:duration('P1M'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(#Q{http://example.com}name, #Q{http://example.com}prefix:name)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">atomic-equal(xs:hexBinary(""), xs:base64Binary(""))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-compare"><head>fn:compare</head><changes><change issue="893" PR="909" date="2024-01-10">The function has been expanded in scope to handle comparison of values other than strings.</change><change issue="1608" PR="1611" date="2024-11-26">The spec has been corrected to note that the function depends on the implicit timezone.</change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">-1</code>, <code nobreak="false">0</code>, or <code nobreak="false">1</code>, depending on whether
            the first value is less than, equal to, or greater than the second value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="compare" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value1" type="xs:anyAtomicType?"/><arg name="value2" type="xs:anyAtomicType?"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone, and static base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The function compares two atomic items <code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> for order, and
            returns the integer value <code nobreak="false">-1</code>, <code nobreak="false">0</code>, or <code nobreak="false">+1</code>,
            depending on whether <code nobreak="false">$value1</code> is less than, equal to, or greater than
            <code nobreak="false">$value2</code>, respectively.</p><p>This function is transitive and symmetric. For example:</p><ulist><item><p>If <code nobreak="false">compare(A, B)</code> returns zero, then <code nobreak="false">compare(B, A)</code>
            returns zero.</p></item><item><p>If <code nobreak="false">compare(A, B)</code> returns -1, then <code nobreak="false">compare(B, A)</code>
            returns +1.</p></item><item><p>If <code nobreak="false">compare(A, B)</code> and <code nobreak="false">compare(B, C)</code> both
            return -1, then <code nobreak="false">compare(A, C)</code> also returns -1.</p></item></ulist><p>If either <code nobreak="false">$value1</code> or <code nobreak="false">$value2</code> is the empty sequence,
            the function returns the empty sequence.</p><p>Otherwise, the result is determined as follows:</p><olist><item><p>If <code nobreak="false">$value1</code> is an instance of <code nobreak="false">xs:string</code>,
                  <code nobreak="false">xs:anyURI</code> or <code nobreak="false">xs:untypedAtomic</code>, and if
                  <code nobreak="false">$value2</code> is an instance of <code nobreak="false">xs:string</code>, <code nobreak="false">xs:anyURI</code>
                  or <code nobreak="false">xs:untypedAtomic</code>, the values are compared as strings, and the
                  result reflects the order according to the rules of the collation that is used.</p><p>The collation is determined according to the rules in
                  <specref ref="choosing-a-collation"/>.</p><note><p>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 <code nobreak="false">"http://www.w3.org/2005/xpath-functions/collation/codepoint"</code>
               explicitly as the third argument.</p></note></item><item><p>If both <code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are instances of
                  <code nobreak="false">xs:numeric</code>, the function relies on a total order, which is
                  defined as follows:</p><olist><item><p>A value <code nobreak="false">$f</code> of type <code nobreak="false">xs:float</code> is in all cases equal
                     to the value <code nobreak="false">xs:double($f)</code>. The remaining rules therefore only consider
                     instances of <code nobreak="false">xs:double</code> and <code nobreak="false">xs:decimal</code>.</p></item><item><p><code nobreak="false">NaN</code> is equal to itself and less than any other value.</p></item><item><p>Negative infinity is equal to itself and less than any other
                     value except <code nobreak="false">NaN</code>.</p></item><item><p>Positive infinity is equal to itself and greater than any other
                     value.</p></item><item><p>Negative zero is equal to positive zero.</p></item><item><p>Other <code nobreak="false">xs:double</code> and <code nobreak="false">xs:decimal</code> values (that is,
                     values other than the infinities, <code nobreak="false">NaN</code>, 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
                     <code nobreak="false">xs:double</code> values to <code nobreak="false">xs:decimal</code> using an implementation
                     of <code nobreak="false">xs:decimal</code> that imposes no limits on precision or scale, or an
                     implementation whose limits are such that all <code nobreak="false">xs:double</code> values can
                     be represented precisely.</p></item></olist><note><p>Every <code nobreak="false">xs:double</code> other than <code nobreak="false">NaN</code> and <code nobreak="false">±INF</code>,
                     has a mathematical value of the form <code nobreak="false">m × 2^e</code>, 
                     where <var>m</var> is an integer whose absolute value is less than 2^53, 
                     and <var>e</var> is an integer between -1075 and 970, inclusive. This is the value
                     that is used in comparisons.</p><p>Practical difficulties arise because the typical string representations of 
                  an <code nobreak="false">xs:double</code>, such as <code nobreak="false">3.1</code>, cannot be precisely
                  represented by values of the form <code nobreak="false">m × 2^e</code>, but are instead converted
                  to the best available approximation, which will often not be exactly equal
                  to an <code nobreak="false">xs:decimal</code> expressed using the same lexical form.</p></note></item><item><p>If both <code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are instances of
                  <code nobreak="false">xs:boolean</code>, the result is 
                  <code nobreak="false">fn:compare(xs:integer($value1), xs:integer($value2))</code></p><note><p>This means that <code nobreak="false">false</code> is 
                  treated as less than <code nobreak="false">true</code>.</p></note></item><item><p>If <code nobreak="false">$value1</code> is an instance of <code nobreak="false">xs:hexBinary</code> or
                  <code nobreak="false">xs:base64Binary</code>, and if <code nobreak="false">$value2</code> is an instance of
                  <code nobreak="false">xs:hexBinary</code> or <code nobreak="false">xs:base64Binary</code>, then:</p><olist><item><p>Let <code nobreak="false">$A</code> be the sequence of integers, in the range (0 to 255), representing
                     the octets of <code nobreak="false">$value1</code>, in order; and let <code nobreak="false">$B</code> similarly
                     be the sequence of integers representing the octets of <code nobreak="false">$value2</code>.</p></item><item><p>If <code nobreak="false">$A</code> is empty and <code nobreak="false">$B</code> is empty return zero.</p></item><item><p>If <code nobreak="false">$A</code> is empty and <code nobreak="false">$B</code> is not empty return -1.</p></item><item><p>Let <code nobreak="false">$C</code> be the value of <code nobreak="false">fn:compare(fn:head($A), fn:head($B))</code>.</p></item><item><p>If <code nobreak="false">$C</code> is non-zero, then return <code nobreak="false">$C</code>.</p></item><item><p>Otherwise, return the result of applying these rules recursively
                  to <code nobreak="false">fn:tail($A)</code> and <code nobreak="false">fn:tail($B)</code></p></item></olist></item><item><p>If both <code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are instances of
                  the same primitive type <var>T</var>, where <var>T</var> is one of the
                  types <code nobreak="false">xs:dateTime</code>, <code nobreak="false">xs:date</code>, <code nobreak="false">xs:time</code>,
                  <code nobreak="false">xs:gYear</code>, <code nobreak="false">xs:gYearMonth</code>, <code nobreak="false">xs:gMonth</code>,
                  <code nobreak="false">gMonthDay</code>, or <code nobreak="false">gDay</code>, then:</p><olist><item><p>Each of the values is converted to an <code nobreak="false">xs:dateTime</code>
                     value as follows:</p><olist><item><p>The value is considered as a tuple with seven fields
                        (year, month, day, hours, minutes, seconds, timezone) as defined by
                        the functions <function>fn:year-from-dateTime</function>,
                        <function>fn:month-from-dateTime</function>, and so on.</p></item><item><p>Any absent components, other than the timezone, are substituted 
                           with the corresponding components of the 
                           <code nobreak="false">xs:dateTime</code> value <code nobreak="false">1972-01-01T00:00:00</code>
                        to produce an <code nobreak="false">xs:dateTime</code> value.</p></item><item><p>If the timezone component is absent, it is substituted
                        with the implicit timezone from the dynamic context.</p><note><p>The <code nobreak="false">xs:dateTime</code> <code nobreak="false">1972-01-01T00:00:00</code>
                        is arbitrary. The only constraint is that the year must be a leap year
                        (so that the <code nobreak="false">xs:gYearMonth</code> value <code nobreak="false">--02-29</code> 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.</p></note></item></olist></item><item><p>The result of the function is then the result of comparing the
                     <term>starting instants</term> of these two <code nobreak="false">xs:dateTime</code>
                     values according to the algorithm defined in section 3.2.7.4 of <bibref ref="xmlschema-2"/> (
            <quote>Order relation on dateTime</quote> for <code nobreak="false">xs:dateTime</code> values with
            timezones).</p></item></olist></item><item><p>If both <code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are instances of
                  <code nobreak="false">xs:duration</code>, then:</p><olist><item><p>Let <code nobreak="false">$M1</code> and <code nobreak="false">$M2</code>
                  be the months components of the two durations, and let <code nobreak="false">$S1</code>
                  and <code nobreak="false">$S2</code> be the seconds components of the two durations.</p></item><item><p>Let <code nobreak="false">$C</code> be <code nobreak="false">fn:compare($M1, $M2)</code>.</p></item><item><p>If <code nobreak="false">$C</code> is non-zero, return <code nobreak="false">$C</code>.</p></item><item><p>Otherwise, return <code nobreak="false">fn:compare($S1, $S2)</code>.</p></item></olist><note><p>The result matches the real-world semantics of durations in many cases,
               for example:</p><ulist><item><p>When both values are zero-length durations.</p></item><item><p>When both values are have an equal months component (in particular when
                     both have a zero months component).</p></item><item><p>When both values are have an equal seconds component (in particular when
                     both have a zero seconds component).</p></item><item><p>When both values have a seconds component that is less than the number
                  of seconds in the shortest month.</p></item></ulist><p>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 (<code nobreak="false">PT1M</code>) is considered greater than one hundred days
                  (<code nobreak="false">PT100D</code>).</p><p>Previous versions of this specification allowed durations to be compared
                  only if both were instances of <code nobreak="false">xs:dateTimeDuration</code> or
                  <code nobreak="false">xs:yearMonthDuration</code>. 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.</p></note></item><item><p>If both <code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are instances of
                  <code nobreak="false">xs:QName</code>, then:</p><olist><item><p>Let <code nobreak="false">$N1</code> and <code nobreak="false">$N2</code>
                  be the result of applying the function <function>fn:namespace-uri-from-QName</function>
                        to the two values, and let <code nobreak="false">$L1</code>
                  and <code nobreak="false">$L2</code> be the result of applying the function
                        <function>local-name-from-QName</function> to the two values.</p></item><item><p>Let <code nobreak="false">$CPC</code> be <code nobreak="false">"http://www.w3.org/2005/xpath-functions/collation/codepoint"</code>.</p></item><item><p>Let <code nobreak="false">$C</code> be <code nobreak="false">fn:compare($N1, $N2, $CPC)</code>.</p></item><item><p>If <code nobreak="false">$C</code> is non-zero, return <code nobreak="false">$C</code>.</p></item><item><p>Otherwise, return <code nobreak="false">fn:compare($L1, $L2, $CPC)</code>.</p></item></olist></item><item><p>If both <code nobreak="false">$value1</code> and <code nobreak="false">$value2</code> are instances of 
                  <code nobreak="false">xs:NOTATION</code>, return <code nobreak="false">fn:compare(xs:QName($value1), xs:QName($value2))</code>.</p></item><item><p>For any other combination of types, a type error
                  <xerrorref spec="XP" class="TY" code="0004"/> is raised. In particular, this means that
               an error is raised when comparing two atomic items that belong to different
               <xspecref spec="DM40" ref="dt-type-family">type families</xspecref>.</p></item></olist></def></gitem><gitem><label>Notes</label><def><note><p>For numeric values, consider the <code nobreak="false">xs:double</code> value written as
            <code nobreak="false">0.1e0</code> and the <code nobreak="false">xs:decimal</code> value written as <code nobreak="false">0.1</code>:
            The mathematical magnitude of this <code nobreak="false">xs:double</code> value is 
            <code nobreak="false">0.1000000000000000055511151231257827021181583404541015625</code>.
            Therefore, <code nobreak="false">compare(0.1e0, 0.1)</code> returns <code nobreak="false">+1</code>. By contrast,
            <code nobreak="false">0.1e0 lt 0.1</code> is <code nobreak="false">false</code> and <code nobreak="false">0.1e0 eq 0.1</code>
            is <code nobreak="false">true</code>, because those expressions convert the <code nobreak="false">xs:decimal</code> value
            <code nobreak="false">0.1</code> to the <code nobreak="false">xs:double</code> value <code nobreak="false">0.1e0</code>
            before the comparison.</p><p>Although operations such as sorting and the <function>fn:min</function> and <function>fn:max</function>
            functions invoke <function>fn:compare</function> to perform numeric comparison, these functions
            in some cases treat <code nobreak="false">NaN</code> differently.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare('abc', 'abc')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare('Strasse', 'Straße')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare('Strasse', 'Straße')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p><p><emph>(Assuming the default collation equates <quote>ss</quote> and
                  the German letter <quote>ß</quote>.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">compare(
  'Strasse',
  'Straße',
  collation({ 'lang': 'de', 'strength': 'primary' })
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">0</eg><p><emph>(The specified collation equates <quote>ss</quote> and the German
                  letter <quote>ß</quote>.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare('text', parse-xml('&lt;xml&gt;text&lt;/xml&gt;'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(9, 10)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(123, 123.0)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:double('NaN'), xs:float('NaN'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:double('NaN'), xs:double('-INF'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:double('-INF'), -23)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(1, 1e0)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(1.1, 1.1e0)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(1.2, 1.2e0)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">+1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(9999, xs:double('INF'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(false(), true())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:hexBinary(''), xs:base64Binary(''))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:hexBinary('0001'), xs:hexBinary('0002'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:hexBinary('00FF'), xs:hexBinary('FF'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:time('23:59:59'), xs:time('00:00:00'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:time('12:00:00Z'), xs:time('13:00:00+01:00'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:date('2001-01-01+01:00'), xs:date('2001-01-01+00:00'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:duration('P1Y'), xs:duration('P13M'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:duration('P1Y'), xs:duration('P1Y3M4D'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(xs:duration('P1Y'), xs:duration('P1000D'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">+1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(#space, #xml:space)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">compare(#Q{http://example.com/ns}index, #Q{http://example.com/ns}xmp:index)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-contains-subsequence"><head>fn:contains-subsequence</head><changes><change issue="92" PR="222" date="2022-11-01">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Determines whether one sequence contains another as a contiguous subsequence, using a supplied callback function to compare items.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="contains-subsequence" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="subsequence" type="item()*"/><arg name="compare" type="(fn(item(), item()) as xs:boolean?)?" default="fn:deep-equal#2" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function returns <code nobreak="false">true</code> if <code nobreak="false">$input</code> contains a consecutive subsequence matching <code nobreak="false">$subsequence</code>,
            when items are compared using the <code nobreak="false">$compare</code> function.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">some $i in 0 to count($input) - count($subsequence)
satisfies (
  every $j in 1 to count($subsequence)
  satisfies $compare($input[$i + $j], $subsequence[$j])   
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>There is no requirement that the <code nobreak="false">$compare</code> function should have the traditional qualities
            of equality comparison. The result is well-defined, for example, even if <code nobreak="false">$compare</code> is not transitive
            or not symmetric.</p><p>A return value of <code nobreak="false">()</code> from the function is treated as <code nobreak="false">false</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-subsequence((), ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-subsequence(1 to 10, 3 to 6)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-subsequence(1 to 10, (2, 4, 6))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-subsequence(1 to 10, ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-subsequence(1 to 10, 1 to 10)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-subsequence(1 to 10, 5)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains-subsequence(
  1 to 10,
  103 to 105,
  fn($x, $y) { $x mod 100 = $y mod 100 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains-subsequence(
  ("A", "B", "C", "D"),
  ("b", "c"),
  fn($x, $y) {
    compare(
      $x,
      $y,
      "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
    ) eq 0
  }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $chap := parse-xml("&lt;doc&gt;&lt;chap&gt;&lt;h1/&gt;&lt;p/&gt;&lt;p/&gt;&lt;footnote/&gt;&lt;/chap&gt;&lt;/doc&gt;")//chap
return contains-subsequence(
  $chap ! child::*,
  $chap ! child::p,
  op("is")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(True because the <code nobreak="false">p</code> children of the <code nobreak="false">chap</code> element form a contiguous subsequence.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-subsequence(10 to 20, (5, 3, 1), op("gt"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains-subsequence(
  ("Alpha", "Beta", "Gamma", "Delta"), ("B", "G"),
  starts-with#2
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains-subsequence(
  ("Zero", "Alpha", "Beta", "Gamma", "Delta", "Epsilon"),
  1 to 4,
  fn($x, $y) { ends-with($x, 'a') }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(True because there is a run of 4 consecutive items ending in <code nobreak="false">"a"</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-deep-equal"><head>fn:deep-equal</head><changes><change issue="930" PR="933" date="2024-01-16">When comments and processing instructions are ignored, any text nodes either side of the
            comment or processing instruction are now merged prior to comparison.</change><change issue="934 1167" PR="1191" date="2024-05-21">The <code nobreak="false">$options</code> parameter has been added, 
               absorbing the <code nobreak="false">$collation</code> parameter.</change><change issue="99 1142" PR="1120 1150" date="2024-04-09">A callback function can be supplied for comparing individual items.</change><change issue="2139" PR="2168" date="2025-08-19">Atomic items of types <code nobreak="false">xs:hexBinary</code> 
            and <code nobreak="false">xs:base64Binary</code> are now mutually comparable. In rare cases, where an
            application uses both types and assumes they are distinct, this can represent a backwards
            incompatibility.</change></changes><glist><gitem><label>Summary</label><def><p> 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<phrase>,
               or maps with matching entries, or arrays with matching members.</phrase></p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="deep-equal" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input1" type="item()*"/><arg name="input2" type="item()*"/><arg name="options" type="(xs:string | map(*))?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>The <code nobreak="false">$options</code> argument defines additional parameters controlling
            how the comparison is done. If it is supplied as a map, then the <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><p>For backwards compatibility reasons, the <code nobreak="false">$options</code> argument can also be set
            to a string containing a collation name. Supplying a string <code nobreak="false">$S</code> for this argument is equivalent
            to supplying the map <code nobreak="false">{ 'collation': $S }</code>.</p><p>If the two sequences (<code nobreak="false">$input1</code> and <code nobreak="false">$input2</code>) 
            are both empty, the function returns <code nobreak="false">true</code>.</p><p>If the two sequences are of different lengths, the function returns
            <code nobreak="false">false</code>.</p><p>If the two sequences are of the same length, the comparison is controlled by the 
            <code nobreak="false">ordered</code> option:</p><ulist><item><p>By default, the option is <code nobreak="false">true</code>: The function returns
            <code nobreak="false">true</code> if and only if every item in the sequence <code nobreak="false">$input1</code> is
            deep-equal to the item at the same position in the sequence <code nobreak="false">$input2</code>.
            </p></item><item><p>If the option is set to <code nobreak="false">false</code>, the function returns
            <code nobreak="false">false</code> if and only if every item in the sequence <code nobreak="false">$input1</code>
            is deep-equal to an item at some position in the sequence <code nobreak="false">$input2</code>,
            and vice versa.</p></item></ulist><p>The rules for
            deciding whether two items are deep-equal appear below.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows. The detailed rules
            for the interpretation of each option appear later.</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="base-uri" type="xs:boolean" occur="opt"/><arg name="collation" type="xs:string" occur="opt"/><arg name="comments" type="xs:boolean" occur="opt"/><arg name="debug" type="xs:boolean" occur="opt"/><arg name="id-property" type="xs:boolean" occur="opt"/><arg name="idrefs-property" type="xs:boolean" occur="opt"/><arg name="in-scope-namespaces" type="xs:boolean" occur="opt"/><arg name="items-equal" type="fn(item(), item()) as xs:boolean?" occur="opt"/><arg name="map-order" type="xs:boolean" occur="opt"/><arg name="namespace-prefixes" type="xs:boolean" occur="opt"/><arg name="nilled-property" type="xs:boolean" occur="opt"/><arg name="normalization-form" type="xs:string?" occur="opt"/><arg name="ordered" type="xs:boolean" occur="opt"/><arg name="processing-instructions" type="xs:boolean" occur="opt"/><arg name="timezones" type="xs:boolean" occur="opt"/><arg name="type-annotations" type="xs:boolean" occur="opt"/><arg name="type-variety" type="xs:boolean" occur="opt"/><arg name="typed-values" type="xs:boolean" occur="opt"/><arg name="unordered-elements" type="xs:QName*" occur="opt"/><arg name="whitespace" type="enum(&#34;preserve&#34;, &#34;strip&#34;, &#34;normalize&#34;)" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">base-uri?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether the <code nobreak="false">base-uri</code> of a node is significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">collation?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Identifies a collation which is used at all levels
                     of recursion when strings are compared (but not when names are compared), according to
                     the rules in <specref ref="choosing-a-collation"/>. If the argument is not supplied,
                     or if it is empty, then the default collation from the 
                     dynamic context of the caller is used.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">fn:default-collation()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">comments?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether comments are significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">debug?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Requests diagnostics in the case where the function returns <code nobreak="false">false</code>.
                     When this option is set and the two inputs are found to be not equal, the implementation
                     <rfc2119>should</rfc2119> output messages (in an implementation-dependent format and to
                     an implementation-dependent destination) indicating the nature of the differences that
                     were found.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">id-property?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether the <code nobreak="false">id</code> property of elements and attributes is significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">idrefs-property?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether the <code nobreak="false">idrefs</code> property of elements and attributes is significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">in-scope-namespaces?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether the in-scope namespaces of elements are significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">items-equal?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">A user-supplied function to test whether two items
                     are considered equal. The function can return <code nobreak="false">true</code>
                     or <code nobreak="false">false</code> to indicate that two items are or are not
                     equal, overriding the normal rules that would apply to those items;
                     or it can return the empty sequence, to indicate that the normal
                     rules should be followed. Note that returning <code nobreak="false">()</code>
                     is <emph>not</emph> equivalent to returning <code nobreak="false">false</code>.
                  <ulist><item><p><term>Type: </term><code nobreak="false">fn(item(), item()) as xs:boolean?</code></p></item><item><p><term>Default: </term><code nobreak="false">fn:void#0</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">map-order?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether the order of entries in maps is significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">namespace-prefixes?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether namespace prefixes in <code nobreak="false">xs:QName</code> values (particularly
                     the names of elements and attributes) are significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">nilled-property?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether the <code nobreak="false">nilled</code> property of elements and attributes is significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">normalization-form?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">If present, indicates that text and attributes are converted to the specified
                     Unicode normalization form prior to comparison. The value is as for the corresponding
                     argument of <function>fn:normalize-unicode</function>.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">ordered?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Controls whether the top-level order of the items of the input sequences
                    is considered.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">processing-instructions?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether processing instructions are significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">timezones?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether timezones in date/time values are significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">type-annotations?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether type annotations are significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">type-variety?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether the variety of the type annotation of an element 
                     (whether it has complex content or simple content) is significant.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">typed-values?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Determines whether nodes are compared using their typed values rather than
                     their string values.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">unordered-elements?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">A list of QNames of elements considered to be unordered: that is, their child
                     elements may appear in any order.
                  <ulist><item><p><term>Type: </term><code nobreak="false">xs:QName*</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">whitespace?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><phrase diff="chg" at="2023-03-13">Determines the extent to which whitespace 
                     is treated as significant. The value
                     <code nobreak="false">preserve</code> retains all whitespace. The value <code nobreak="false">strip</code> ignores text nodes
                     consisting entirely of whitespace.
                     The value <code nobreak="false">normalize</code> ignores whitespace text nodes in the same way as
                     the <code nobreak="false">strip</code> option, and additionally compares text and attribute nodes after 
                     normalizing whitespace in accordance with the rules of the <function>fn:normalize-space</function> 
                     function. The detailed rules, given below, also take into account type annotations and 
                     <code nobreak="false">xml:space</code> attributes.
                  </phrase>
                  <ulist><item><p><term>Type: </term><code nobreak="false">enum("preserve", "strip", "normalize")</code></p></item><item><p><term>Default: </term><code nobreak="false">preserve</code></p></item></ulist></td></tr></tbody></table><note><p>As a general rule for boolean options (but not invariably), the value <code nobreak="false">true</code> indicates 
            that the comparison is more strict. </p></note><p>In the following rules, where a recursive call on <function>fn:deep-equal</function> is made, this is assumed
         to use the same values of <code nobreak="false">$options</code> as the original call.</p><p>The rules reference a function <code nobreak="false">equal-strings</code> which compares two <code nobreak="false">xs:string</code>
            or <code nobreak="false">xs:anyURI</code> values as follows:</p><olist><item><p>If the <code nobreak="false">whitespace</code> option is set to <code nobreak="false">normalize</code>, then each string is processed
               by calling the <function>fn:normalize-space</function> function.</p></item><item><p>If the <code nobreak="false">normalization-form</code> option is present, each string is then normalized
            by calling the <function>fn:normalize-unicode</function> function, supplying the specified normalization
            form.</p></item><item><p>The two strings are then compared for equality under the requested collation.</p></item></olist><p>More formally, the <code nobreak="false">equal-strings</code> function is equivalent to the following
            implementation in XQuery:</p><eg xml:space="preserve">
declare function equal-strings(
  $string1  as xs:string,
  $string2  as xs:string, 
  $options  as map(*)
) as xs:boolean {
  let $n1 := if ($options?normalization-form)
             then normalize-unicode(?, $options?normalization-form) 
             else identity#1
  let $n2 := if ($options?whitespace = "normalize")
             then normalize-space#1 
             else identity#1               
  return compare($n1($n2($string1)), $n1($n2($string2)), $options?collation) eq 0    
}</eg><p>The rules for deciding whether two items <code nobreak="false">$i1</code> and <code nobreak="false">$i2</code> are deep-equal
            are as follows.</p><p>The two items are first compared using the function supplied in the <code nobreak="false">items-equal</code>
            option. If this returns <code nobreak="false">true</code> then the items are deep-equal. If it returns
            <code nobreak="false">false</code> then the items are not deep-equal. If it returns the empty sequence
            (which is always the case if the option is not explicitly specified)
            then the two items are deep-equal if one or more of the following conditions are true:</p><olist><item><p>All of the following conditions are true:</p><olist><item><p><code nobreak="false">$i1</code> is an atomic item.</p></item><item><p><code nobreak="false">$i2</code> is an atomic item.</p></item><item><p>Either the <code nobreak="false">type-annotations</code> option is <code nobreak="false">false</code>, or both atomic items have
                     the same type annotation.</p></item><item><p>One of the following conditions is true:</p><olist><item><p>If both <code nobreak="false">$i1</code> and <code nobreak="false">$i2</code> are instances of
                           <code nobreak="false">xs:string</code>, <code nobreak="false">xs:untypedAtomic</code>, or <code nobreak="false">xs:anyURI</code>,
                           <code nobreak="false">equal-strings($i1, $i2, $collation, $options)</code>
                           returns <code nobreak="false">true</code>.
                        </p></item><item><p>Otherwise, <code nobreak="false">fn:compare($i1, $i2)</code>
                           returns zero.
                        </p></item></olist><p>If <code nobreak="false">$i1</code> and <code nobreak="false">$i2</code> are not comparable, that is,
                        if the expression <code nobreak="false">compare($i1, $i2)</code>  raises an error, then the function
                     returns <code nobreak="false">false</code>; it does not report an error.</p></item><item><p>One of the following conditions is true:</p><olist><item><p>Option <code nobreak="false">namespace-prefixes</code> is <code nobreak="false">false</code>.</p></item><item><p>Neither <code nobreak="false">$i1</code> nor <code nobreak="false">$i2</code> is of type
                        <code nobreak="false">xs:QName</code> or <code nobreak="false">xs:NOTATION</code>.</p></item><item><p><code nobreak="false">$i1</code> and <code nobreak="false">$i2</code> are qualified names with the same namespace prefix.</p></item></olist></item><item><p>One of the following conditions is true:</p><olist><item><p>Option <code nobreak="false">timezones</code> is <code nobreak="false">false</code>.</p></item><item><p>Neither <code nobreak="false">$i1</code> nor <code nobreak="false">$i2</code> is of type
                           <code nobreak="false">xs:date</code>, <code nobreak="false">xs:time</code>, <code nobreak="false">xs:dateTime</code>, 
                           <code nobreak="false">xs:gYear</code>, <code nobreak="false">xs:gYearMonth</code>, <code nobreak="false">xs:gMonth</code>, 
                           <code nobreak="false">xs:gMonthDay</code>, or <code nobreak="false">xs:gDay</code>.</p></item><item><p>Neither <code nobreak="false">$i1</code> nor <code nobreak="false">$i2</code> has a timezone component.</p></item><item><p>Both <code nobreak="false">$i1</code> and <code nobreak="false">$i2</code> have a timezone component and the
                        timezone components are equal.</p></item></olist></item></olist></item><item><p>All of the following conditions are true:</p><olist><item><p><code nobreak="false">$i1</code> is a map.</p></item><item><p><code nobreak="false">$i2</code> is a map.</p></item><item><p>Both maps have the same number of entries.</p></item><item><p>For every entry in the first map, there is an entry in the second map that:</p><olist><item><p>has the <termref def="dt-same-key">same key</termref> (note that the
                              collation is not used when comparing keys), and </p></item><item><p>has the same associated value (compared using the <function>fn:deep-equal</function>
                              function, recursively).</p></item></olist></item><item><p>Either <code nobreak="false">map-order</code> is false, or the entries in both maps appear in the same order,
                     that is, the <var>Nth</var> key in the first map is the <termref def="dt-same-key">same key</termref> as the <var>Nth</var> key in the second map, for all <var>N</var>.</p></item></olist></item><item><p>All the following conditions are true:</p><olist><item><p><code nobreak="false">$i1</code> is an array.</p></item><item><p><code nobreak="false">$i2</code> is an array.</p></item><item><p>Both arrays have the same number of members (<code nobreak="false">array:size($i1) eq
                           array:size($i2)</code>).</p></item><item><p>Members in the same position of both arrays are deep-equal to each other: that is,
                           <code nobreak="false">every $p in 1 to array:size($i1) satisfies deep-equal($i1($p), $i2($p),
                           $collation, $options).</code></p></item></olist></item><item diff="add" at="2023-05-25"><p>All the following conditions are true:</p><olist><item><p><code nobreak="false">$i1</code> is a function item and is not a map or array.</p></item><item><p><code nobreak="false">$i2</code> is a function item and is not a map or array.</p></item><item><p><code nobreak="false">$i1</code> and <code nobreak="false">$i2</code> have the same function identity.
                     The concept of function identity is explained in <xspecref spec="DM40" ref="function-items"/>.</p></item></olist></item><item><p>All the following conditions are true:</p><olist><item><p><code nobreak="false">$i1</code> is a node (specifically, an XNode).</p></item><item><p><code nobreak="false">$i2</code> is a node (specifically, an XNode).</p></item><item><p>Both nodes have the same node kind.</p></item><item><p>Either the <code nobreak="false">base-uri</code> option is <code nobreak="false">false</code>, or both nodes have the same value
                     for their base URI property, or both nodes have an absent base URI.</p></item><item><p>Let <code nobreak="false">significant-children($parent)</code> be the sequence of nodes obtained by applying the following
                  steps to the children of <code nobreak="false">$parent</code>, in turn:</p><olist><item><p>Comment nodes are discarded if the option <code nobreak="false">comments</code> is <code nobreak="false">false</code>.</p></item><item><p>Processing instruction nodes are discarded if the option <code nobreak="false">processing-instructions</code> is <code nobreak="false">false</code>.</p></item><item><p>Adjacent text nodes are merged.</p></item><item><p>Whitespace-only text nodes are discarded if both the following conditions are true:</p><olist><item><p>The option <code nobreak="false">whitespace</code> is set to <code nobreak="false">strip</code>
                                       or <code nobreak="false">normalize</code>; and</p></item><item><p>The text node is not within the scope
                              of an element that has the attribute <code nobreak="false">xml:space="preserve"</code>.</p></item></olist><note><p>Whitespace text nodes will already have been discarded if
                              <code nobreak="false">$parent</code> is a schema-validated element node whose type annotation 
                              is a complex type with an element-only or empty content model.</p></note></item></olist></item><item><p>One of the following conditions is true.</p><olist><item><p>Both nodes are document nodes, and the sequence <code nobreak="false">significant-children($i1)</code> 
                              is deep-equal to the sequence <code nobreak="false">significant-children($i2)</code>.</p></item><item><p>Both nodes are element nodes, and all the following conditions are true:</p><olist><item><p>The two nodes have the same name, that is <code nobreak="false">(node-name($i1) eq
                                    node-name($i2))</code>.</p></item><item><p>Either the option <code nobreak="false">namespace-prefixes</code> is <code nobreak="false">false</code>, or both element
                                    names have the same prefix.</p></item><item><p>Either the option <code nobreak="false">in-scope-namespaces</code> is <code nobreak="false">false</code>, or both element
                                    nodes have the same in-scope namespace bindings.</p></item><item><p>Either the option <code nobreak="false">type-annotations</code> is <code nobreak="false">false</code>, or both
                                    element nodes have the same type annotation.</p></item><item><p>Either the option <code nobreak="false">id-property</code> is <code nobreak="false">false</code>, or both element
                                    nodes have the same value for their <code nobreak="false">is-id</code> property.</p></item><item><p>Either the option <code nobreak="false">idrefs-property</code> is <code nobreak="false">false</code>, or both element
                                    nodes have the same value for their <code nobreak="false">is-idrefs</code> property.</p></item><item><p>Either the option <code nobreak="false">nilled-property</code> is <code nobreak="false">false</code>, or both element
                                    nodes have the same value for their <code nobreak="false">nilled</code> property.</p></item><item><p>One of the following conditions is true:</p><olist><item><p>The option <code nobreak="false">type-variety</code> is <code nobreak="false">false</code>.</p></item><item><p>Both nodes are annotated as having simple content.
                                       For this purpose <term>simple content</term>
                                       means either a simple type or a complex type with simple content.</p></item><item><p>Both nodes are annotated as having complex content. For this purpose 
                                       <term>complex content</term> means a complex type whose variety is mixed, element-only, or
                                       empty.</p></item></olist><note><p>It is a consequence of this rule that, by default, validating a document <var>D</var>
                                       against a schema will usually (but not necessarily) result in a document
                                       that is not deep-equal to <var>D</var>. The exception is when the schema
                                       allows all elements to have mixed content.</p></note></item><item><p>The two nodes have the same number of attributes, and for every attribute
                                    <code nobreak="false">$a1</code> in <code nobreak="false">$i1/@*</code> there exists an attribute
                                    <code nobreak="false">$a2</code> in <code nobreak="false">$i2/@*</code> such that <code nobreak="false">node-name($a1) eq node-name($a2)</code>
                                    and <code nobreak="false">$a1</code> and <code nobreak="false">$a2</code> are deep-equal.</p><note><p>Attributes, like other items, may be compared using the supplied <code nobreak="false">items-equal</code>
                                 function. However, this function will not be called to compare two attribute nodes unless
                                 they have the same name.</p></note></item><item><p> One of the following conditions holds:</p><olist><item><p>Both element nodes are annotated as having simple content (as defined
                                          above), the <code nobreak="false">typed-values</code> option is <code nobreak="false">true</code>, 
                                          and the typed value of <code nobreak="false">$i1</code> is deep-equal
                                          to the typed value of <code nobreak="false">$i2</code>.</p><note><p>The typed value of an element node is used only when the element
                                       has simple content, which means that no error can occur as a result
                                       of atomizing a node with no typed value.</p></note></item><item><p>Both element nodes are annotated as having simple content (as defined
                                          above), the <code nobreak="false">typed-values</code> option is <code nobreak="false">false</code>, 
                                          and the <code nobreak="false">equal-strings</code> function returns <code nobreak="false">true</code> when
                                          applied to the string value of <code nobreak="false">$i1</code> 
                                          and the string value of <code nobreak="false">$i2</code>.</p></item><item><p>Both element nodes have a type annotation that is a complex type with
                                          element-only, mixed, or empty content,
                                          the (common) element name is not present in the <code nobreak="false">unordered-elements</code> option,
                                          and the sequence <code nobreak="false">significant-children($i1)</code> is
                                          deep-equal to the sequence <code nobreak="false">significant-children($i2)</code>.</p></item><item><p>Both element nodes have a type annotation that is a complex type with
                                          element-only, mixed, or empty content,
                                          the (common) element name is present in the <code nobreak="false">unordered-elements</code> option,
                                          and the sequence <code nobreak="false">significant-children($i1)</code> is
                                          deep-equal to some permutation of the sequence <code nobreak="false">significant-children($i2)</code>.</p><note><p>Elements annotated as <code nobreak="false">xs:untyped</code> fall into this category.</p><p>Including an element name in the <code nobreak="false">unordered-elements</code> list is unlikely
                                          to be useful except when the relevant elements have element-only content, but
                                          this is not a requirement: the rules apply equally to elements with mixed content,
                                          or even (trivially) to elements with empty content.</p></note></item></olist></item></olist></item><item><p>Both nodes are attribute nodes, and all the following conditions are true:</p><olist><item><p>The two attribute nodes have the same name, that is <code nobreak="false">(node-name($i1) eq
                                       node-name($i2))</code>.</p></item><item><p>Either the option <code nobreak="false">namespace-prefixes</code> is <code nobreak="false">false</code>, or both
                                 attribute names have the same prefix.</p></item><item><p>Either the option <code nobreak="false">type-annotations</code> is <code nobreak="false">false</code>, or both
                                 attribute nodes have the same type annotation.</p></item><item><p>Either the option <code nobreak="false">id-property</code> is <code nobreak="false">false</code>, or both attribute nodes
                                    have the same value for their <code nobreak="false">is-id</code> property.</p></item><item><p>Either the option <code nobreak="false">idrefs-property</code> is <code nobreak="false">false</code>, or both attribute nodes
                                    have the same value for their <code nobreak="false">is-idrefs</code> property.</p></item><item><p>Let <var>T</var> be true if the option <code nobreak="false">typed-value</code> is true
                                    and both attributes <code nobreak="false">$i1</code> and <code nobreak="false">$i2</code> have a type
                                 annotation other than <code nobreak="false">xs:untypedAtomic</code>.</p><p>Then either <var>T</var> is true and the typed value of <code nobreak="false">$i1</code> 
                                    is deep-equal to the typed value of <code nobreak="false">$i2</code>, or <var>T</var> is false 
                                    and the <code nobreak="false">equal-strings</code> function returns true when applied to the 
                                    string value of <code nobreak="false">$i1</code> and the string value of <code nobreak="false">$i2</code>. </p></item></olist></item><item><p>Both nodes are processing instruction nodes, and all the following conditions are true:</p><olist><item><p>The two nodes have the same name, that is <code nobreak="false">(node-name($i1) eq
                                          node-name($i2))</code>.</p></item><item><p>The <code nobreak="false">equal-strings</code> function returns <code nobreak="false">true</code> when applied to 
                                       the string value of <code nobreak="false">$i1</code> 
                                       and the string value of <code nobreak="false">$i2</code>.</p></item></olist></item><item><p>Both nodes are namespace nodes, and all the following conditions are true:</p><olist><item><p>The two nodes either have the same name or are both nameless, that is
                                    <code nobreak="false">fn:deep-equal(node-name($i1), node-name($i2))</code>.</p></item><item><p>The string value of <code nobreak="false">$i1</code> is equal to the string value of
                                    <code nobreak="false">$i2</code> when compared using the Unicode codepoint collation.</p></item></olist><note><p>Namespace nodes are not considered directly unless they appear in the top-level sequences
                           passed explicitly to the <function>fn:deep-equal</function> function.</p></note></item><item><p>Both nodes are comment nodes, and the <code nobreak="false">equal-strings</code> function 
                              returns <code nobreak="false">true</code> when applied to their string values.</p></item><item><p>Both nodes are text nodes, and the <code nobreak="false">equal-strings</code> function 
                              returns <code nobreak="false">true</code> when applied to their string values.</p></item></olist></item></olist></item><item><p>All the following conditions are true:</p><olist><item><p><code nobreak="false">$i1</code> is a JNode.</p></item><item><p><code nobreak="false">$i2</code> is a JNode.</p></item><item><p>The <term>·jvalue·</term> property of <code nobreak="false">$i1</code>
                  is deep-equal to the <term>·jvalue·</term> property of <code nobreak="false">$i2</code>.</p><note><p>The other properties of the two JNodes, such as <term>·jparent·</term>
                  and <term>·jkey·</term>, are ignored. As with XNodes, deep equality
                  considers only the subtree rooted at the node, and not its position within
                  a containing tree.</p></note></item></olist></item></olist><p>In all other cases the result is <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <xerrorref spec="XP" class="TY" code="0004" type="type"/> if the value of 
            <code nobreak="false">$options</code> includes an entry whose key is defined 
            in this specification, and whose value is not of the permitted type for that key.</p><p>A dynamic error is raised <errorref spec="FO" class="JS" code="0005"/> if the value of 
            <code nobreak="false">$options</code> includes an entry whose key is defined 
            in this specification, and whose value is not a permitted value for that key.</p></def></gitem><gitem><label>Notes</label><def><note><p>By default, whitespace in text nodes and attributes is considered significant. There are various ways
         whitespace differences can be ignored:</p><ulist><item><p>If nodes have been schema-validated, setting the <code nobreak="false">typed-values</code> 
               option to true causes the typed values rather
               than the string values to be compared. This will typically cause whitespace to be ignored
               except where the type of the value is <code nobreak="false">xs:string</code>.</p></item><item><p>Setting the <code nobreak="false">whitespace</code> option to <code nobreak="false">normalize</code> causes all
            text and attribute nodes to have leading and trailing whitespace removed, and intermediate
            whitespace reduced to a single character.</p></item></ulist><p>By default, two nodes are not required to have the same type annotation, and they are not
            required to have the same in-scope namespaces. They may also differ in their parent,
            their base URI, and the values returned by the <code nobreak="false">is-id</code> and
               <code nobreak="false">is-idrefs</code> accessors (see <xspecref spec="DM40" ref="dm-is-id"/> and
               <xspecref spec="DM40" ref="dm-is-idrefs"/>). The order of children is significant,
            but the order of attributes is insignificant. </p><p>By default, the contents of comments and processing instructions are significant only if these nodes
            appear directly as items in the two sequences being compared. The content of a comment
            or processing instruction that appears as a descendant of an item in one of the
            sequences being compared does not affect the result. <phrase diff="chg" at="issue930">In previous versions
            of this specification, the presence of a comment
            or processing instruction, if it caused text to be split across two text nodes, might
            affect the result; this has been changed in 4.0 so that adjacent text nodes are merged
            after comments and processing instructions have been stripped.</phrase></p><p>Comparing items of different kind (for example, comparing an atomic
            item to a node, or a map to an array, or an integer to an <code nobreak="false">xs:date</code>) returns <code nobreak="false">false</code>, 
            it does not return an error. So
            the result of <code nobreak="false">fn:deep-equal(1, current-dateTime())</code> is <code nobreak="false">false</code>.</p><p>The <code nobreak="false">items-equal</code> callback function may be used to override the default rules
         for comparing individual items. For example, it might return <code nobreak="false">true</code> unconditionally
         when comparing two <code nobreak="false">@timestamp</code> attributes, if there is no expectation that the
         two trees will have identical timestamps. Given two nodes <code nobreak="false">$n1</code> and <code nobreak="false">$n2</code>, 
            it might compare them using the <code nobreak="false">is</code> operator, so that instead of comparing the
         descendants of the two nodes, the function simply checks whether they are the same node.
         Given two function items <code nobreak="false">$f1</code> and <code nobreak="false">$f2</code> it might return true unconditionally,
         knowing that there is no effective way to test if the functions are equivalent. Given
         two numeric values, it might return <code nobreak="false">true</code> if they are equal to six decimal places.</p><p>It is good practice for the <code nobreak="false">items-equal</code> callback function to be reflexive,
         symmetric, and transitive; if it is not, then the <function>fn:deep-equal</function> function itself
         will lack these qualities. <emph>Reflexive</emph> means that every item (including <code nobreak="false">NaN</code>)
         should be equal to itself; <emph>symmetric</emph> means that <code nobreak="false">items-equal(A, B)</code>
         should return the same result as <code nobreak="false">items-equal(B, A)</code>, and <emph>transitive</emph>
            means that <code nobreak="false">items-equal(A, B)</code> and <code nobreak="false">items-equal(B, C)</code> should
            imply <code nobreak="false">items-equal(A, C)</code>.</p><p>Setting the <code nobreak="false">ordered</code> option to <code nobreak="false">false</code> or supplying the
            <code nobreak="false">unordered-elements</code> option may result in poor performance when comparing
            long sequences, especially if the <code nobreak="false">items-equal</code> callback function is supplied.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $at := &lt;attendees&gt;
  &lt;name last="Parker" first="Peter"/&gt;
  &lt;name last="Barker" first="Bob"/&gt;
  &lt;name last="Parker" first="Peter"/&gt;
&lt;/attendees&gt;</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">deep-equal($at, $at/*)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">deep-equal($at/name[1], $at/name[2])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">deep-equal($at/name[1], $at/name[3])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">deep-equal($at/name[1], 'Peter Parker')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  $at//name[@first="Bob"], 
  $at//name[@last="Barker"],
  options := { 'items-equal': op('is') } 
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(Tests whether the two input sequences contain exactly the same nodes.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">deep-equal([ 1, 2, 3], [ 1, 2, 3 ])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">deep-equal((1, 2, 3), [ 1, 2, 3 ])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  { 1: 'a', 2: 'b' },
  { 2: 'b', 1: 'a' }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  (1, 2, 3, 4),
  (1, 4, 3, 2),
  options := { 'ordered': false() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  (1, 1, 2, 3),
  (1, 2, 3, 3),
  options := { 'ordered': false() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  parse-xml("&lt;a xmlns='AA'/&gt;"),
  parse-xml("&lt;p:a xmlns:p='AA'/&gt;")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(By default, namespace prefixes are ignored).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  parse-xml("&lt;a xmlns='AA'/&gt;"),
  parse-xml("&lt;p:a xmlns:p='AA'/&gt;"),
  options := { 'namespace-prefixes': true() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg><p><emph>(False because the namespace prefixes differ).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  parse-xml("&lt;a xmlns='AA'/&gt;"),
  parse-xml("&lt;p:a xmlns:p='AA'/&gt;"),
  options := { 'in-scope-namespaces': true() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg><p><emph>(False because the in-scope namespace bindings differ).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  parse-xml("&lt;a&gt;&lt;b/&gt;&lt;c/&gt;&lt;/a&gt;"),
  parse-xml("&lt;a&gt;&lt;c/&gt;&lt;b/&gt;&lt;/a&gt;")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg><p><emph>(By default, order of elements is significant).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  parse-xml("&lt;a&gt;&lt;b/&gt;&lt;c/&gt;&lt;/a&gt;"),
  parse-xml("&lt;a&gt;&lt;c/&gt;&lt;b/&gt;&lt;/a&gt;"),
  options := { 'unordered-elements': #a }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(The <code nobreak="false">unordered-elements</code> option means that the ordering of the children
               of <code nobreak="false">a</code> is ignored.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  parse-xml("&lt;para style='bold'&gt;&lt;span&gt;x&lt;/span&gt;&lt;/para&gt;"),
  parse-xml("&lt;para style=' bold'&gt; &lt;span&gt;x&lt;/span&gt;&lt;/para&gt;")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg><p><emph>(By default, both the leading whitespace in the <code nobreak="false">style</code> attribute
                  and the whitespace text node preceding the <code nobreak="false">span</code> element are significant.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  parse-xml("&lt;para style='bold'&gt;&lt;span&gt;x&lt;/span&gt;&lt;/para&gt;"),
  parse-xml("&lt;para style=' bold'&gt; &lt;span&gt;x&lt;/span&gt;&lt;/para&gt;"),
  options := { 'whitespace': 'normalize' }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(The <code nobreak="false">whitespace</code> option causes both the leading space
                  in the attribute value and the whitespace preceding the 
                  <code nobreak="false">span</code> element to be ignored.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  (1, 2, 3), 
  (1.0007, 1.9998, 3.0005),
  options := { 'items-equal': fn($x, $y) {
    if (($x, $y) instance of xs:numeric+) {
      abs($x - $y) lt 0.001
    }
  } }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(For numeric values, the callback function tests whether they
               are approximately equal. For any other items, it returns the empty sequence,
               so the normal comparison rules apply.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">deep-equal(
  (1, 2, 3, 4, 5), 
  (1, 2, 3, 8, 5),
  options := { 'items-equal': fn($x, $y) {
    trace((), `comparing { $x } and { $y }`)
  } }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg><p><emph>(The callback function traces which items are being compared,
                  without changing the result of the comparison.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-distinct-values"><head>fn:distinct-values</head><changes><change>Changed in 4.0 to use transitive equality comparisons for numeric
         values.</change><change issue="628" PR="987" date="2024-02-06">The order of results is now prescribed; 
            it was previously implementation-dependent.</change><change issue="2139" PR="2168" date="2025-08-14">Atomic items of types <code nobreak="false">xs:hexBinary</code> 
            and <code nobreak="false">xs:base64Binary</code> are now mutually comparable. In rare cases, where an
            application uses both types and assumes they are distinct, this can represent a backwards
            incompatibility.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the values that appear in a sequence, with duplicates eliminated.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="distinct-values" return-type="xs:anyAtomicType*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>The function returns the sequence that results from removing from <code nobreak="false">$values</code> all
            but one of a set of values that are 
            <termref def="dt-contextually-equal"/> to one another,
            when compared using the collation selected according to the rules in <specref ref="choosing-a-collation"/> and the implicit timezone from the dynamic context.
            </p><p>The ordering of the result is as follows:</p><ulist><item><p>For any set of values that compare equal, the one that is
            returned is the one that appears first in <code nobreak="false">$values</code>.</p></item><item><p>The items that are returned appear in the order of their first 
            appearance within <code nobreak="false">$values</code>.</p></item></ulist></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter($values, 
  fn($item, $pos) {
    empty(
      filter(
        subsequence($values, 1, $pos - 1),
        deep-equal(?, $item, $collation)
      )
    )
  }
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$values</code> is the empty sequence, the function returns the empty sequence.</p><p>Values of type <code nobreak="false">xs:untypedAtomic</code> are compared as if they were of type
            <code nobreak="false">xs:string</code>.</p><p>Values that cannot be compared, because the <code nobreak="false">eq</code> operator is not defined for
            their types, are considered to be distinct.</p><p>For numeric values, the rules are the same as <function>fn:atomic-equal</function>:
            positive and negative zero are treated as equal, <code nobreak="false">NaN</code> is treated
            as equal to <code nobreak="false">NaN</code>, and values of different numeric types are converted
            to unlimited-precision decimals for comparison purposes.</p><p> If <code nobreak="false">xs:dateTime</code>, <code nobreak="false">xs:date</code> or <code nobreak="false">xs:time</code> values do not
            have a timezone, they are considered to have the implicit timezone provided by the
            dynamic context for the purpose of comparison. Note that <code nobreak="false">xs:dateTime</code>,
            <code nobreak="false">xs:date</code> or <code nobreak="false">xs:time</code> values can compare equal even if their
            timezones are different.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">distinct-values((1, 2.0, 3, 2))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2.0, 3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">distinct-values((
  xs:untypedAtomic("cherry"),
  xs:untypedAtomic("plum"),
  xs:untypedAtomic("plum")
))</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:untypedAtomic("cherry"), xs:untypedAtomic("plum")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-duplicate-values"><head>fn:duplicate-values</head><changes><change issue="123 628 1869" PR="614 987" date="2023-07-18">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the values that appear in a sequence more than once.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="duplicate-values" return-type="xs:anyAtomicType*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>The items of <code nobreak="false">$values</code> are compared against each other, according to the
            rules of <function>fn:distinct-values</function> and with <code nobreak="false">$collation</code> as the collation
            selected according to the rules in <specref ref="choosing-a-collation"/>.</p><p>From each resulting set of values that are considered equal, one value will be
            returned if the set contains more than one value.</p><p>Specifically, the function returns those items in <code nobreak="false">$values</code> that are
         <termref def="dt-contextually-equal"/> to exactly one item appearing earlier in the sequence.</p><p>This means that the ordering of the result is as follows:</p><ulist><item><p>For any set of values that compare equal, the one that is
               returned is the one that appears second in <code nobreak="false">$values</code>.</p></item><item><p>The items that are returned appear in the order of their second
               appearance within <code nobreak="false">$values</code>.</p></item></ulist></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">filter(
  $values, 
  fn($item, $pos) {
    count(
      filter(
        subsequence($values, 1, $pos - 1),
        deep-equal(?, $item, $collation)
      )
    ) eq 1
  }
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>The comparison rules are exactly the same as the <function>fn:distinct-values</function>
         function.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">duplicate-values((1, 2, 3, 1.0, 1e0))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">duplicate-values(1 to 100)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">duplicate-values(('1', &lt;x&gt;1&lt;/x&gt;, '2', 2))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:untypedAtomic("1")</code></p><p><emph>(The string <code nobreak="false">"1"</code> and the untyped value of the
                  element node are considered equal, whereas the string <code nobreak="false">"2"</code>
                  and the integer are considered unequal.)</emph></p></td></tr><tr><td colspan="2" rowspan="1"><p>Raise an error for duplicates in an ID sequence:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $ids := duplicate-values(//@id)
where exists($ids)
return error((), 'Duplicate IDs found: ' || string-join($ids, ', '))</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-ends-with-subsequence" diff="add" at="B"><head>fn:ends-with-subsequence</head><changes><change issue="92" PR="222" date="2022-11-01">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Determines whether one sequence ends with another, using a supplied callback function to compare items.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="ends-with-subsequence" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="subsequence" type="item()*"/><arg name="compare" type="(fn(item(), item()) as xs:boolean?)?" default="fn:deep-equal#2" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function returns <code nobreak="false">true</code> if <code nobreak="false">$input</code> ends with <code nobreak="false">$subsequence</code>,
            when items are compared using the <code nobreak="false">$compare</code> function.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">starts-with-subsequence(reverse($input), reverse($subsequence), $compare)</eg></def></gitem><gitem><label>Notes</label><def><note><p>There is no requirement that the <code nobreak="false">$compare</code> function should have the traditional qualities
            of equality comparison. The result is well-defined, for example, even if <code nobreak="false">$compare</code> is not transitive
            or not symmetric.</p><p>A return value of <code nobreak="false">()</code> from the function is treated as <code nobreak="false">false</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">ends-with-subsequence((), ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">ends-with-subsequence(1 to 10, 5 to 10)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">ends-with-subsequence(1 to 10, ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">ends-with-subsequence(1 to 10, 1 to 10)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">ends-with-subsequence(1 to 10, 10)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with-subsequence(
  1 to 10,
  108 to 110,
  fn($x, $y) { $x mod 100 = $y mod 100 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with-subsequence(
  ("A", "B", "C"),
  ("b", "c"),
  fn($x, $y) {
    compare(
      $x,
      $y,
      "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
    ) eq 0
  }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $p := parse-xml("&lt;doc&gt;&lt;chap&gt;&lt;p/&gt;&lt;p/&gt;&lt;/chap&gt;&lt;/doc&gt;")//p[2]
return ends-with-subsequence(
  $p/ancestor::node()[last()],
  $p/root(),
  op("is")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">ends-with-subsequence(10 to 20, 1 to 5, op("gt"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with-subsequence(
  ("Alpha", "Beta", "Gamma"),
  ("B", "G"),
  starts-with#2
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with-subsequence(
  ("Alpha", "Beta", "Gamma", "Delta"),
  1 to 2,
  fn($x, $y) { string-length($x) eq 5 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(True because the last two items in the input sequence have a string length of 5.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-index-of"><head>fn:index-of</head><changes><change issue="2216" PR="2256" date="2025-12-01">In the interests of consistency,
         the <function>index-of</function> function now defines equality to mean
         <termref def="dt-contextually-equal"/>. This has the implication that
         <code nobreak="false">NaN</code> is now considered equal to <code nobreak="false">NaN</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a sequence of positive integers giving the positions within the sequence
               <code nobreak="false">$input</code> of items that are <termref def="dt-contextually-equal"/> 
            to <code nobreak="false">$target</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="index-of" return-type="xs:integer*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="xs:anyAtomicType*"/><arg name="target" type="xs:anyAtomicType"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence of positive integers giving the 1-based positions within the
            sequence <code nobreak="false">$input</code> of items that are <termref def="dt-contextually-equal"/> 
            to <code nobreak="false">$target</code>.</p><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. This collation is used when string comparison is
            required.</p><p>The result sequence is in ascending numeric order.</p></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$input</code> is the empty sequence, or if no item in
            <code nobreak="false">$input</code> matches <code nobreak="false">$target</code>, then the function returns the empty
            sequence.</p><p>No error occurs if non-comparable values are encountered. So when comparing two atomic
            items, the effective boolean value of <code nobreak="false">fn:index-of($a, $b)</code> is <code nobreak="false">true</code> if
               <code nobreak="false">$a</code> and <code nobreak="false">$b</code> are equal, <code nobreak="false">false</code> if they are not equal or not
            comparable.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">index-of((10, 20, 30, 40), 35)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">index-of((10, 20, 30, 30, 20, 10), 20)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2, 5</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">index-of(
  ("a", "sport", "and", "a", "pastime"),
  "a"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 4</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">index-of(
  ("a", "b", "c"),
  "B",
  "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">index-of(current-date(), 23)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">index-of([ 1, [ 5, 6 ], [ 6, 7 ] ], 6)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3, 4</code></p><p><emph>(The array is atomized to a sequence of five integers).</emph></p></td></tr><tr><td colspan="2" rowspan="1"><p>If <code nobreak="false">@a</code> is an attribute of type <code nobreak="false">xs:NMTOKENS</code> whose string
               value is <code nobreak="false">"red green blue"</code>, and whose typed value is therefore
                  <code nobreak="false">("red", "green", "blue")</code>, then <code nobreak="false">fn:index-of(@a, "blue")</code>
               returns <code nobreak="false">3</code>. This is because the function calling mechanism atomizes the
               attribute node to produce a sequence of three <code nobreak="false">xs:NMTOKEN</code> values.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-starts-with-subsequence" diff="add" at="B"><head>fn:starts-with-subsequence</head><changes><change issue="92" PR="222" date="2022-11-01">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Determines whether one sequence starts with another, using a supplied callback function to compare items.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="starts-with-subsequence" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="subsequence" type="item()*"/><arg name="compare" type="(fn(item(), item()) as xs:boolean?)?" default="fn:deep-equal#2" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function returns <code nobreak="false">true</code> if <code nobreak="false">$input</code> starts with <code nobreak="false">$subsequence</code>,
         when items are compared using the <code nobreak="false">$compare</code> function.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">count($input) ge count($subsequence) and
every(for-each-pair($input, $subsequence, $compare))</eg></def></gitem><gitem><label>Notes</label><def><note><p>There is no requirement that the <code nobreak="false">$compare</code> function should have the traditional qualities
            of equality comparison. The result is well-defined, for example, even if <code nobreak="false">$compare</code> is not transitive
         or not symmetric. A return value of <code nobreak="false">()</code> from the function is treated as <code nobreak="false">false</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">starts-with-subsequence((), ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">starts-with-subsequence(1 to 10, 1 to 5)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">starts-with-subsequence(1 to 10, ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">starts-with-subsequence(1 to 10, 1 to 10)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">starts-with-subsequence(1 to 10, 1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with-subsequence(
  1 to 10,
  101 to 105,
  fn($x, $y) { $x mod 100 = $y mod 100 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with-subsequence(
  ("A", "B", "C"),
  ("a", "b"),
  fn($x, $y) {
    compare(
      $x,
      $y,
      "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
    ) eq 0
  }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $p := parse-xml("&lt;doc&gt;&lt;chap&gt;&lt;p/&gt;&lt;p/&gt;&lt;/chap&gt;&lt;/doc&gt;")//p[2]
return starts-with-subsequence(
  $p/ancestor::*[1],
  $p/parent::*,
  op("is")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">starts-with-subsequence(10 to 20, 1 to 5, op("gt"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with-subsequence(
  ("Alpha", "Beta", "Gamma"),
  ("A", "B"),
  starts-with#2
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with-subsequence(
  ("Alpha", "Beta", "Gamma", "Delta"),
  1 to 3,
  fn($x, $y) { ends-with($x, 'a' ) }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(True because the first three items in the input sequence end with <code nobreak="false">"a"</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="cardinality-functions"><head>Asserting cardinality</head><p>The following functions assert the cardinality of their sequence arguments.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:exactly-one</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">$input</code> if it contains exactly one item. Otherwise, raises an error.
         </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:one-or-more</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">$input</code> if it contains one or more items. Otherwise, raises an error.
         </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:zero-or-one</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">input</code> if it contains zero or one items. Otherwise, raises an
            error.</td></tr></tbody></table><p>The functions <function>fn:zero-or-one</function>, <function>fn:one-or-more</function>, and
                    <function>fn:exactly-one</function> defined in this section, check that the cardinality
                    of a sequence is in the expected range. These functions were originally defined
                    for use with processors that enforced strict static typing. 
                    For example, the function call <code nobreak="false">fn:remove($seq, fn:index-of($seq2, 'abc'))</code>
                    requires the result of the call on <function>fn:index-of</function> to be a singleton integer, 
                    but the static type system could not infer this; writing the expression as 
                    <code nobreak="false">fn:remove($seq, fn:exactly-one(fn:index-of($seq2, 'abc')))</code> 
                    would provide a suitable static type at query analysis time, and ensure that the length of the sequence is
                    correct with a dynamic check at query execution time.</p><p>The 4.0 specifications no longer define strict static typing as an option, so the utility
            of these functions has declined. They may still serve a purpose, however, as assertions
            signaling expected preconditions both to the processor and to anyone reading the code.</p><p>The type signatures for these functions deliberately declare the argument type as
                    <code nobreak="false">item()*</code>, permitting a sequence of any length. A more restrictive
                    signature would defeat the purpose of the function, which is to defer
                    cardinality checking until query execution time.</p><div3 id="func-exactly-one"><head>fn:exactly-one</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">$input</code> if it contains exactly one item. Otherwise, raises an error.
         </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="exactly-one" return-type="item()" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Except in error cases, the function returns <code nobreak="false">$input</code> unchanged.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression, except in error cases.</p><eg xml:space="preserve">if (count($input) eq 1) 
then $input 
else error(#Q{http://www.w3.org/2005/xqt-errors}FORG0005))</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RG" code="0005"/> if <code nobreak="false">$input</code> is an
            empty sequence or a sequence containing more than one item.</p></def></gitem></glist></div3><div3 id="func-one-or-more"><head>fn:one-or-more</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">$input</code> if it contains one or more items. Otherwise, raises an error.
         </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="one-or-more" return-type="item()+" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Except in error cases, the function returns <code nobreak="false">$input</code> unchanged.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression, except in error cases.</p><eg xml:space="preserve">if (count($input) ge 1) 
then $input 
else error(#Q{http://www.w3.org/2005/xqt-errors}FORG0004))</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RG" code="0004"/> if <code nobreak="false">$input</code> is an
            empty sequence.</p></def></gitem></glist></div3><div3 id="func-zero-or-one"><head>fn:zero-or-one</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">input</code> if it contains zero or one items. Otherwise, raises an
            error.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="zero-or-one" return-type="item()?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Except in error cases, the function returns <code nobreak="false">$input</code> unchanged.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression, except in error cases.</p><eg xml:space="preserve">if (count($input) le 1) 
then $input 
else error(#Q{http://www.w3.org/2005/xqt-errors}FORG0003))</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RG" code="0003"/> if <code nobreak="false">$input</code>
            contains more than one item.</p></def></gitem></glist></div3></div2><div2 id="aggregate-functions"><head>Aggregate functions</head><p>Aggregate functions take a sequence as argument and return a single value
                    computed from values in the sequence. Except for <function>fn:count</function>, the
                    sequence must consist of values of a single type or one if its subtypes, or they
                    must be numeric. <code nobreak="false">xs:untypedAtomic</code> 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.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:count</code></td><td rowspan="1" colspan="1">Returns the number of items in a sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:all-equal</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if all items in a supplied sequence (after atomization) are 
            <termref def="dt-contextually-equal"/>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:all-different</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if no two items in a supplied sequence are 
            <termref def="dt-contextually-equal"/>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:avg</code></td><td rowspan="1" colspan="1">Returns the average of the values in the input sequence <code nobreak="false">$values</code>, that is, the
            sum of the values divided by the number of values.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:max</code></td><td rowspan="1" colspan="1">Returns a value that is greater than or equal to every other value appearing in the input sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:min</code></td><td rowspan="1" colspan="1">Returns a value that is less than or equal to every other value appearing in the input sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:sum</code></td><td rowspan="1" colspan="1">Returns a value obtained by adding together the values in <code nobreak="false">$values</code>.</td></tr></tbody></table><div3 id="func-count"><head>fn:count</head><glist><gitem><label>Summary</label><def><p>Returns the number of items in a sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="count" return-type="xs:integer" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the number of items in <code nobreak="false">$input</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function is defined as follows, making use of primitive constructors and accessors defined
		in <bibref ref="xpath-datamodel-40"/>.</p><eg xml:space="preserve">dm:count($input)</eg></def></gitem><gitem><label>Notes</label><def><note><p>The function returns <code nobreak="false">0</code> if <code nobreak="false">$input</code> is the empty sequence.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $tree := &lt;doc&gt;&lt;chap&gt;&lt;p/&gt;&lt;p/&gt;&lt;p/&gt;&lt;/chap&gt;&lt;/doc&gt;</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $seq2 := (98.5, 98.3, 98.9)</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $seq3 := ()</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">count($tree//chap/p)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">count($seq3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">count($seq2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">count($seq2[. &gt; 100])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">count([])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">count([ 1, 2, 3 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-all-equal" diff="add" at="B"><head>fn:all-equal</head><changes><change date="2022-09-20">New in 4.0. Originally proposed under the name <code role="example" nobreak="false">fn:uniform</code></change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if all items in a supplied sequence (after atomization) are 
            <termref def="dt-contextually-equal"/>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="all-equal" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>The result of the function <code nobreak="false">fn:all-equal($values, $collation)</code> is <code nobreak="false">true</code> if and only if the result
            of <code nobreak="false">fn:count(fn:distinct-values($values, $collation)) le 1</code> is <code nobreak="false">true</code> (that is, if the sequence
            is empty, or if all the items in the sequence are equal under the rules of the 
            <function>fn:distinct-values</function> function).</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-equal((1, 2, 3))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-equal((1, 1.0, 1.0e0))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-equal("one")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-equal(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-equal((xs:float('NaN'), xs:double('NaN')))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">all-equal(
  ("ABC", "abc"),
  "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-equal(//p/@class)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Returns <code nobreak="false">true</code> if all
                <code nobreak="false">p</code> elements have the same value for <code nobreak="false">@class</code>.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-equal(* ! node-name())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Returns <code nobreak="false">true</code> if all
               element children of the context node have the same name.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-all-different" diff="add" at="B"><head>fn:all-different</head><changes><change date="2022-09-20">New in 4.0. Originally proposed under the name <code role="example" nobreak="false">fn:unique</code></change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if no two items in a supplied sequence are 
            <termref def="dt-contextually-equal"/>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="all-different" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>The result of the function <code nobreak="false">fn:all-different($values, $collation)</code> is <code nobreak="false">true</code> if and only if the result
            of <code nobreak="false">fn:count(fn:distinct-values($values, $collation)) eq fn:count($values)</code> is <code nobreak="false">true</code> 
            (that is, if the sequence
            is empty, or if all the items in the sequence are 
            <termref def="dt-contextually-equal">contextually unequal</termref> under the rules used by the 
            <function>fn:distinct-values</function> function).</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-different((1, 2, 3))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-different((1, 1.0, 1.0e0))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-different("one")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">all-different(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">all-different(
  ("ABC", "abc"),
  "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:all-different(//employee/@ssn)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Returns <code nobreak="false">true</code> if no two employees have the same value for their
            <code nobreak="false">@ssn</code> attribute.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:all-different(* ! fn:node-name())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Returns <code nobreak="false">true</code> if all
                  element children of the context node have distinct names.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-avg"><head>fn:avg</head><changes><change issue="1682" PR="1734" date="2025-01-27">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.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the average of the values in the input sequence <code nobreak="false">$values</code>, that is, the
            sum of the values divided by the number of values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="avg" return-type="xs:anyAtomicType?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$values</code> is the empty sequence, the empty sequence is returned.</p><p>Any item in <code nobreak="false">$values</code> that is an instance of <code nobreak="false">xs:untypedAtomic</code> 
            is cast to <code nobreak="false">xs:double</code>. </p><p>After this conversion, one of the following conditions must be true:</p><olist><item><p>Every item in <code nobreak="false">$values</code> is an instance of <code nobreak="false">xs:yearMonthDuration</code>.</p></item><item><p>Every item in <code nobreak="false">$values</code> is an instance of <code nobreak="false">xs:dayTimeDuration</code>.</p></item><item><p>Every item in <code nobreak="false">$values</code> is an instance of <code nobreak="false">xs:numeric</code>.</p></item></olist><p>The function returns the average of the values as <code nobreak="false">sum($values) div
            count($values)</code>; but the implementation may use an otherwise equivalent algorithm
            that avoids arithmetic overflow. Note that the <function>fn:sum</function> 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.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains
            items of incompatible types, as described above.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $d1 := xs:yearMonthDuration("P20Y")</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $d2 := xs:yearMonthDuration("P10M")</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $seq3 := (3, 4, 5)</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">avg($seq3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">4.0</code></p><p><emph>(The result is of type <code nobreak="false">xs:decimal</code>.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">avg(($d1, $d2))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:yearMonthDuration("P10Y5M")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">avg(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">avg((xs:float('INF'), xs:float('-INF')))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:float('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">avg(($seq3, xs:float('NaN')))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:float('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">fn:avg(($d1, $seq3))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FORG0006.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-max"><head>fn:max</head><changes><change issue="866" PR="881" date="2023-12-06">The way that <function>fn:min</function> and <function>fn:max</function> compare numeric values of different types
              has changed. The most noticeable effect is that when these functions are applied to a sequence of
                 <code nobreak="false">xs:integer</code> or <code nobreak="false">xs:decimal</code> values, the result is an <code nobreak="false">xs:integer</code> or 
                 <code nobreak="false">xs:decimal</code>, rather than the result of converting this to an <code nobreak="false">xs:float</code> 
               or <code nobreak="false">xs:double</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a value that is greater than or equal to every other value appearing in the input sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="max" return-type="xs:anyAtomicType?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>Any item in <code nobreak="false">$values</code> that is an instance of <code nobreak="false">xs:untypedAtomic</code>
            is first cast to <code nobreak="false">xs:double</code>. The resulting sequence is referred to as the
            converted sequence.</p><p>All pairs of values in the converted sequence must be mutually comparable. Two values <var>A</var>
            and <var>B</var> are mutually
            comparable if <code nobreak="false">fn:compare(<var>A</var>, <var>B</var>)</code> raises no error.</p><p>If the converted sequence is empty, the function returns the empty sequence.</p><p>If the converted sequence contains the value <code nobreak="false">NaN</code>, the value
            <code nobreak="false">NaN</code> is returned
            <phrase>(as an <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> as appropriate)</phrase>.</p><p>Two items <var>A</var>
            and <var>B</var> from the converted sequence are compared 
            by calling <code nobreak="false">fn:compare(<var>A</var>, <var>B</var>, $collation)</code>, 
            where <code nobreak="false">$collation</code>
               is determined by the rules in <specref ref="choosing-a-collation"/>:</p><p>The result of the function is a value from the converted sequence that is greater than 
            or equal to every other value under the above rules. If there is more than one such value, then it is 
            <termref def="implementation-dependent">implementation-dependent</termref>
            which of them is returned.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains
            items of incompatible types, as described above.</p></def></gitem><gitem><label>Notes</label><def><note><p>If there are two or items that are
            “equal highest”, the specific item whose value is returned is <termref def="implementation-dependent">implementation-dependent</termref>. This can arise for example if two different strings
            compare equal under the selected collation, or if two different <code nobreak="false">xs:dateTime</code>
            values compare equal despite being in different timezones.</p><p>If the converted sequence contains exactly one value then that value is returned.</p><p>The default type when the <function>fn:max</function> function is applied to
            <code nobreak="false">xs:untypedAtomic</code> values is <code nobreak="false">xs:double</code>. This differs from the
            default type for operators such as <code nobreak="false">lt</code>, and for sorting in XQuery and XSLT,
            which is <code nobreak="false">xs:string</code>.</p><p>In version 4.0, if <code nobreak="false">$values</code> is a sequence of <code nobreak="false">xs:decimal</code> values
            (including the case where it is a sequence of <code nobreak="false">xs:integer</code> values), then
            the result will be one of these <code nobreak="false">xs:decimal</code> or <code nobreak="false">xs:integer</code> values. 
            In earlier versions it would
            be the result of converting this <code nobreak="false">xs:decimal</code> to <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">max((3, 2, 1))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">max([ 3, 2, 1 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p><p><emph>(Arrays are atomized).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">max((
  xs:integer(5),
  xs:float(5),
  xs:double(0)
))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">5</code></p><p><emph>(The result may be either the <code nobreak="false">xs:integer</code> or the <code nobreak="false">xs:float</code>,
                  since they are equal.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">max((
  xs:float(0.0E0),
  xs:float(-0.0E0)
))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:float(0.0e0)</code></p><p><emph>(The result may be either positive or negative zero, since they are equal.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">max((
  current-date(),
  xs:date("2100-01-01")
))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:date("2100-01-01")</code></p><p><emph>(Assuming that the current date is during the 21st century.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">max(("a", "b", "c"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"c"</code></p><p><emph>(Assuming a typical default collation.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">max((3, 4, "Zero"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FORG0006.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-min"><head>fn:min</head><changes><change issue="866" PR="881" date="2023-12-06">The way that <function>fn:min</function> and <function>fn:max</function> compare numeric values of different types
              has changed. The most noticeable effect is that when these functions are applied to a sequence of
                 <code nobreak="false">xs:integer</code> or <code nobreak="false">xs:decimal</code> values, the result is an <code nobreak="false">xs:integer</code> or 
                 <code nobreak="false">xs:decimal</code>, rather than the result of converting this to an <code nobreak="false">xs:float</code> or 
               <code nobreak="false">xs:double</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a value that is less than or equal to every other value appearing in the input sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="min" return-type="xs:anyAtomicType?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>Any item in <code nobreak="false">$values</code> that is an instance of <code nobreak="false">xs:untypedAtomic</code>
            is first cast to <code nobreak="false">xs:double</code>. The resulting sequence is referred to as the
            converted sequence.</p><p>All pairs of values in the converted sequence must be mutually comparable. Two values <var>A</var>
            and <var>B</var> are mutually
            comparable if <code nobreak="false">fn:compare(<var>A</var>, <var>B</var>)</code> raises no error.</p><p>If the converted sequence is empty, the function returns the empty sequence.</p><p>If the converted sequence contains the value <code nobreak="false">NaN</code>, the value
            <code nobreak="false">NaN</code> is returned
            <phrase>(as an <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> as appropriate)</phrase>.</p><p>Two items <var>A</var>
            and <var>B</var> from the converted sequence are compared 
            by calling <code nobreak="false">fn:compare(<var>A</var>, <var>B</var>, $collation)</code>, 
            where <code nobreak="false">$collation</code>
               is determined by the rules in <specref ref="choosing-a-collation"/>:</p><p>The result of the function is a value from the converted sequence that is less than 
            or equal to every other value under the above rules. If there is more than one such value, then it is 
            <termref def="implementation-dependent">implementation-dependent</termref>
            which of them is returned.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains
            items of incompatible types, as described above.</p></def></gitem><gitem><label>Notes</label><def><note><p>If there are two or items that are
            “equal lowest”, the specific item whose value is returned is <termref def="implementation-dependent">implementation-dependent</termref>. This can arise for example if two different strings
            compare equal under the selected collation, or if two different <code nobreak="false">xs:dateTime</code>
            values compare equal despite being in different timezones.</p><p>If the converted sequence contains exactly one value then that value is returned.</p><p>The default type when the <function>fn:min</function> function is applied to
               <code nobreak="false">xs:untypedAtomic</code> values is <code nobreak="false">xs:double</code>. This differs from the
            default type for operators such as <code nobreak="false">lt</code>, and for sorting in XQuery and XSLT,
            which is <code nobreak="false">xs:string</code>.</p><p>In version 4.0, if <code nobreak="false">$values</code> is a sequence of <code nobreak="false">xs:decimal</code> values
            (including the case where it is a sequence of <code nobreak="false">xs:integer</code> values), then
            the result will be one of these <code nobreak="false">xs:decimal</code> or <code nobreak="false">xs:integer</code> values. 
            In earlier versions it would
            be the result of converting this <code nobreak="false">xs:decimal</code> to <code nobreak="false">xs:float</code> 
            or <code nobreak="false">xs:double</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">min((3, 4, 5))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">min([ 3, 4, 5 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p><p><emph>(Arrays are atomized).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">min((
  xs:integer(5),
  xs:float(5),
  xs:double(10)
))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">5</code></p><p><emph>(The result may be either the <code nobreak="false">xs:integer</code> or the <code nobreak="false">xs:float</code>,
               since they are equal.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">min((
  xs:float(0.0E0),
  xs:float(-0.0E0)
))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:float(0.0e0)</code></p><p><emph>(The result may be either positive or negative zero, since they are equal.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">min((
  current-date(),
  xs:date("1900-01-01")
))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:date("1900-01-01")</code></p><p><emph>(Assuming that the current date is set to a reasonable
                  value.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">min(("a", "b", "c"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a"</code></p><p><emph>(Assuming a typical default collation.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">min((3, 4, "Zero"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FORG0006.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-sum"><head>fn:sum</head><changes><change issue="1682" PR="1734" date="2025-01-27">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.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a value obtained by adding together the values in <code nobreak="false">$values</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="sum" return-type="xs:anyAtomicType?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/><arg name="zero" type="xs:anyAtomicType?" default="0"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Any value of type <code nobreak="false">xs:untypedAtomic</code> in <code nobreak="false">$values</code> is cast to
               <code nobreak="false">xs:double</code>. The items in the resulting sequence may be reordered in an
            arbitrary order. The resulting sequence is referred to below as the converted
            sequence.</p><p>If the converted sequence is empty, then the function returns
            the value of the argument <code nobreak="false">$zero</code>.</p><p>In other cases the items in the converted sequence are added pairwise according
         the rules of the <code nobreak="false">+</code> operator.</p><p>Specifically, the result of the function is the value of the
            expression:</p><eg xml:space="preserve">
if (empty($c)) then $zero
else if (count($c) eq 1) then $c
else head($c) + sum(tail($c))</eg><p>where <code nobreak="false">$c</code> is the converted sequence.</p><p>This has the effect that a type error will occur unless one of the following
         conditions is satisfied:</p><olist><item><p>Every item in <code nobreak="false">$values</code> is an instance of <code nobreak="false">xs:yearMonthDuration</code>.</p></item><item><p>Every item in <code nobreak="false">$values</code> is an instance of <code nobreak="false">xs:dayTimeDuration</code>.</p></item><item><p>Every item in <code nobreak="false">$values</code> is an instance of <code nobreak="false">xs:numeric</code>.</p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <errorref class="RG" code="0006"/> if the input sequence contains
            items of incompatible types, as described above.</p></def></gitem><gitem><label>Notes</label><def><note><p>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”.</p><p diff="add" at="2023-01-17">The explicit or implicit value of 
            the <code nobreak="false">$zero</code> argument is used only when the input sequence is empty, not
            when a non-empty sequence sums to zero. For example, <code nobreak="false">sum((-1, +1), xs:double('NaN'))</code>
            returns the <code nobreak="false">xs:integer</code> value <code nobreak="false">0</code>, not <code nobreak="false">NaN</code>.</p><p>The sum of a sequence of integers will be an integer, while the
            sum of a numeric sequence that includes at least one <code nobreak="false">xs:double</code> will be an
               <code nobreak="false">xs:double</code>.</p><p>If the converted sequence contains exactly one value then that value is returned.</p><p>If the converted sequence contains the value <code nobreak="false">NaN</code>, <code nobreak="false">NaN</code> is
            returned.</p><p>In edge cases the fact that the input sequence may be reordered makes the result
            slightly unpredictable. For example, if the input contains two <code nobreak="false">xs:decimal</code>
            values and an <code nobreak="false">xs:float</code>, then the decimal values might be added using
            decimal arithmetic, or they might both be converted to <code nobreak="false">xs:float</code> 
            (potentially losing precision) before any arithmetic is performed.
            </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $d1 := xs:yearMonthDuration("P20Y")</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $d2 := xs:yearMonthDuration("P10M")</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $seq1 := ($d1, $d2)</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $seq3 := (3, 4, 5)</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sum(($d1, $d2))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:yearMonthDuration("P20Y10M")</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">sum(
  $seq1[. lt xs:yearMonthDuration('P3M')],
  xs:yearMonthDuration('P0M')
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:yearMonthDuration("P0M")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sum($seq3)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">12</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sum(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sum((),())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sum((1 to 100)[. lt 0], 0) </code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sum(($d1, $d2), "ein Augenblick")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:yearMonthDuration("P20Y10M")</code></p><p><emph>(There is no requirement that the <code nobreak="false">$zero</code> value should be
                  the same type as the items in <code nobreak="false">$value</code>, or even that it should belong to
                  a type that supports addition.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sum([ 1, 2, 3 ])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">6</code></p><p><emph>(Atomizing an array returns the sequence obtained by atomizing its members.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sum([ [ 1, 2 ], [ 3, 4 ] ])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">10</code></p><p><emph>(Atomizing an array returns the sequence obtained by atomizing its members.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:sum(($d1, 9E1))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Raises error FORG0006.</p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="basic-hofs"><head>Basic higher-order functions</head><p>The following functions take function items as an argument.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:apply</code></td><td rowspan="1" colspan="1">Makes a dynamic call on a function with an argument list supplied in the form of an array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:do-until</code></td><td rowspan="1" colspan="1">Processes a supplied value repeatedly, continuing when some condition is false,
            and returning the value that satisfies the condition.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:every</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if every item in the input sequence matches a supplied predicate.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:filter</code></td><td rowspan="1" colspan="1">Returns those items from the sequence <code nobreak="false">$input</code> for which the supplied function
               <code nobreak="false">$predicate</code> returns <code nobreak="false">true</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:fold-left</code></td><td rowspan="1" colspan="1">Processes the supplied sequence from left to right, applying the supplied function
            repeatedly to each item in turn, together with an accumulated result value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:fold-right</code></td><td rowspan="1" colspan="1">Processes the supplied sequence from right to left, applying the supplied function
            repeatedly to each item in turn, together with an accumulated result value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:for-each</code></td><td rowspan="1" colspan="1">Applies the function item <code nobreak="false">$action</code> to every item from the sequence <var>$input</var>
            in turn, returning the concatenation of the resulting sequences in order.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:for-each-pair</code></td><td rowspan="1" colspan="1">Applies the function item <code nobreak="false">$action</code> to successive pairs of items taken one from
               <code nobreak="false">$input1</code> and one from <code nobreak="false">$input2</code>, returning the concatenation of the
            resulting sequences in order.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:highest</code></td><td rowspan="1" colspan="1">Returns a value that is greater than or equal to every other value appearing in the input sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:index-where</code></td><td rowspan="1" colspan="1">Returns the positions in an input sequence of items that match a supplied predicate.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:lowest</code></td><td rowspan="1" colspan="1">Returns those items from a supplied sequence that have the lowest value of a sort key, where
            the sort key can be computed using a caller-supplied function.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:partial-apply</code></td><td rowspan="1" colspan="1">Performs partial application of a function item by binding values to selected arguments.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:partition</code></td><td rowspan="1" colspan="1">Partitions 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.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:scan-left</code></td><td rowspan="1" colspan="1">Produces the sequence of successive partial results from 
           the evaluation of <function>fn:fold-left</function> with the same arguments.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:scan-right</code></td><td rowspan="1" colspan="1">Produces the sequence of successive partial results from 
           the evaluation of <function>fn:fold-right</function> with the same arguments.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:some</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if at least one item in the input sequence matches a supplied predicate.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:sort</code></td><td rowspan="1" colspan="1">Sorts a supplied sequence, based on the value of a sort key supplied as a function.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:sort-by</code></td><td rowspan="1" colspan="1">Sorts a supplied sequence, based on the value of a number of sort keys supplied as functions.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:sort-with</code></td><td rowspan="1" colspan="1">Sorts a supplied sequence, according to the order induced by the supplied comparator
            functions.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:subsequence-where</code></td><td rowspan="1" colspan="1">Returns a contiguous sequence of items from <code nobreak="false">$input</code>, with the start and end
         points located by applying predicates.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:take-while</code></td><td rowspan="1" colspan="1">Returns items from the input sequence prior to the first one that fails to match a supplied predicate.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:transitive-closure</code></td><td rowspan="1" colspan="1">Returns all the GNodes reachable from a given start GNode by applying a supplied function repeatedly.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:while-do</code></td><td rowspan="1" colspan="1">Processes a supplied value repeatedly, continuing while some condition remains true,
            and returning the first value that does not satisfy the condition.</td></tr></tbody></table><p>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.</p><div3 id="func-apply"><head>fn:apply</head><changes><change issue="1267" PR="1280" date="2024-06-18">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.</change></changes><glist><gitem><label>Summary</label><def><p>Makes a dynamic call on a function with an argument list supplied in the form of an array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="apply" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="function" type="fn(*)"/><arg name="arguments" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The result of the function is obtained by invoking the supplied function <code nobreak="false">$function</code> with arguments
         taken from the members of the supplied array <code nobreak="false">$arguments</code>. The first argument of the function call is the first
         member of <code nobreak="false">$arguments</code>, the second argument is the second member of <code nobreak="false">$arguments</code>, and so on.</p><p>The arity of the supplied function <code nobreak="false">$function</code> must be less than or equal to the size 
            of the array <code nobreak="false">$arguments</code>.</p><p>The effect of calling <code nobreak="false">fn:apply($f, [$a, $b, $c, ...])</code> is the same as the effect of the dynamic function call 
            <code nobreak="false">$f($a, $b, $c, ....)</code>. For example, the coercion rules are applied to the supplied arguments
            in the usual way. Among other things this means that excess arguments are ignored.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised if the arity of the function <code nobreak="false">$function</code> is greater than the size of the
            array <code nobreak="false">$arguments</code> (<errorref spec="FO" class="AP" code="0001"/>).
         </p></def></gitem><gitem><label>Notes</label><def><note><p>The function is useful where the arity of a function item is not known statically.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">apply(concat#3, [ "a", "b", "c" ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"abc"</code></p></td></tr><tr><td colspan="2" rowspan="1"><p>The expression <code nobreak="false">apply($f, array:subarray([ "a", "b", "c", "d", "e", "f" ], 1, function-arity($f)))</code> 
               calls the supplied function <code nobreak="false">$f</code> supplying the number of arguments required by its arity.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-do-until"><head>fn:do-until</head><changes><change issue="946" PR="962" date="2024-01-23">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Processes a supplied value repeatedly, continuing when some condition is false,
            and returning the value that satisfies the condition.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="do-until" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="action" type="fn(item()*, xs:integer) as item()*"/><arg name="predicate" type="fn(item()*, xs:integer) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function behaves as follows:</p><olist><item><p><code nobreak="false">$pos</code> is initially set to <code nobreak="false">1</code>.</p></item><item><p><code nobreak="false">$action($input, $pos)</code> is evaluated, and the resulting value
                  is used as a new <code nobreak="false">$input</code>.</p></item><item><p><code nobreak="false">$predicate($input, $pos)</code> is evaluated. If the result is
                  <code nobreak="false">true</code>, the function returns the value of <code nobreak="false">$input</code>.
                  Otherwise, the process repeats from step 2 with <code nobreak="false">$pos</code> incremented by
                  <code nobreak="false">1</code>.</p><p>When the predicate returns the empty sequence, this is treated as <code nobreak="false">false</code>.</p></item></olist></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function delivers the same result as the following XQuery implementation.</p><eg xml:space="preserve">declare %private function do-until-helper(
  $input     as item()*,
  $action    as fn(item()*, xs:integer) as item()*,
  $predicate as fn(item()*, xs:integer) as xs:boolean?,
  $pos       as xs:integer
) as item()* {
  let $result := $action($input, $pos)
  return if ($predicate($result, $pos)) then (
    $result
  ) else (
    do-until-helper($result, $action, $predicate, $pos + 1)
  )
};

declare function do-until(
  $input     as item()*,
  $action    as fn(item()*, xs:integer) as item()*,
  $predicate as fn(item()*, xs:integer) as xs:boolean?
) as item()* {
  do-until-helper($input, $action, $predicate, 1)
};</eg></def></gitem><gitem><label>Notes</label><def><note><p>Do-until loops are very common in procedural programming languages, and this function
            provides a way to write functionally clean and interruptible iterations without
            side-effects. A new value is computed and tested until a given condition fails. Depending
            on the use case, the value can be a simple atomic item or an arbitrarily complex data
            structure.</p><p>The function <function>fn:while-do</function> can be used to perform the action after the
            first predicate test.</p><p>Note that, just as when writing recursive functions, it is easy to construct infinite
            loops.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
do-until(
  (),
  fn($value, $pos) { $value, $pos * $pos },
  fn($value) { foot($value) &gt; 50  }
)
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 4, 9, 16, 25, 36, 49, 64</eg><p><emph>(The loop is interrupted once the last value of the generated sequence
                  is greater than 50.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
do-until(
  (1, 0),
  fn($value) { $value[1] + $value[2], $value },
  fn($value) { avg($value) &gt; 10 }
)
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">55, 34, 21, 13, 8, 5, 3, 2, 1, 1, 0</eg><p><emph>(The computation is continued as long as the average of the first
                  Fibonacci numbers is smaller than 10.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-every" diff="add" at="A"><head>fn:every</head><changes><change date="2022-09-13">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if every item in the input sequence matches a supplied predicate.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="every" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="predicate" type="(fn(item(), xs:integer) as xs:boolean?)?" default="fn:boolean#1" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns true if <code nobreak="false">$input</code> is empty, or if <code nobreak="false">$predicate($item, $pos)</code>
            returns true for every item <code nobreak="false">$item</code> at position <code nobreak="false">$pos</code> (1-based) in <code nobreak="false">$input</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">count(filter($input, $predicate)) = count($input)</eg></def></gitem><gitem><label>Error Conditions</label><def><p>An error is raised if the <code nobreak="false">$predicate</code> function raises an error. In particular,
         when the default predicate <code nobreak="false">fn:boolean#1</code> is used, an error is raised if an
         item has no effective boolean value.</p></def></gitem><gitem><label>Notes</label><def><note><p>It is possible for the supplied <code nobreak="false">$predicate</code> to be a function whose arity is less than two.
            The coercion rules mean that the additional parameters are effectively ignored. Frequently a predicate
            function will only consider the item itself, and disregard its position in the sequence.</p><p>The predicate is required to return either <code nobreak="false">true</code>, <code nobreak="false">false</code>, or the empty
            sequence (which is treated as <code nobreak="false">false</code>). A predicate such as <code nobreak="false">fn { self::h1 }</code>
            results in a type error because it returns a node, not a boolean.</p><p>The implementation <rfc2119>may</rfc2119> deliver a result as soon as one item is found for which the predicate
         returns <code nobreak="false">false</code>; it is not required to evaluate the predicate for every item,
         nor is it required to examine items sequentially from left to right.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">every(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">every((1 = 1, 2 = 2, 3 = 4))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">every((), boolean#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">every((1, 3, 7), fn { . mod 2 = 1 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">every(-5 to +5, fn { . ge 0 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">every(
  ("January", "February", "March", "April",
   "September", "October", "November", "December"),
  contains(?, "r")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">every(
  ("January", "February", "March", "April",
   "September", "October", "November", "December")
  =!&gt; contains("r")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">every((1, 2, number('NaN')))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p><p><emph>(The effective boolean value of NaN is false.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">every(1 to 5, fn($num, $pos) { $num = $pos })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $dl := &lt;dl&gt;&lt;dt&gt;Morgawr&lt;/dt&gt;&lt;dd&gt;Sea giant&lt;/dd&gt;&lt;/dl&gt;
return every($dl/*, fn($elem, $pos) {
  name($elem) = (
    if (($pos mod 2)) then "dt" else "dd"
  )
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-filter"><head>fn:filter</head><changes><change issue="516" PR="828" date="2023-11-14">The <code nobreak="false">$predicate</code> callback function accepts an optional position argument.</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Returns those items from the sequence <code nobreak="false">$input</code> for which the supplied function
               <code nobreak="false">$predicate</code> returns <code nobreak="false">true</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="filter" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="predicate" type="fn(item(), xs:integer) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence containing those items from <code nobreak="false">$input</code>
            for which <code nobreak="false">$predicate($item, $pos)</code> returns <code nobreak="false">true</code>, where <code nobreak="false">$item</code>
            is the item in question, and <code nobreak="false">$pos</code> is its 1-based ordinal position within <code nobreak="false">$input</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">for-each(
  $input,
  fn($item, $pos) { if ($predicate($item, $pos)) { $item } }
)</eg></def></gitem><gitem><label>Error Conditions</label><def><p>As a consequence of the function signature and the function calling rules, a type error
            occurs if the supplied <code nobreak="false">$predicate</code> function returns anything other than a single
               <code nobreak="false">xs:boolean</code> item or the empty sequence; there is no conversion to an effective boolean
            value, but the empty sequence is interpreted as false.</p></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$predicate</code> is an arity-1 function,
            the function call <code nobreak="false">fn:filter($input, $predicate)</code> has a very similar effect to the
            expression <code nobreak="false">$input[$predicate(.)]</code>. There are some differences, however. In the case of
               <function>fn:filter</function>, the function <code nobreak="false">$F</code> is required to return an optional boolean;
            there is no special treatment for numeric predicate values, and no conversion to an
            effective boolean value. Also, with a filter expression <code nobreak="false">$input[$predicate(.)]</code>,
            the focus within the predicate is different from that outside; this means that the use of a
            context-sensitive function such as <code nobreak="false">fn:lang#1</code> will give different results in
            the two cases.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">filter(1 to 10, fn($a) { $a mod 2 = 0 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2, 4, 6, 8, 10</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">filter(parse-xml('&lt;doc&gt;&lt;a id="2"/&gt;&lt;a/&gt;&lt;/doc&gt;')//a, fn { @id eq "2" })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">&lt;a id="2"/&gt;</eg><p><emph>(The function returns <code nobreak="false">()</code> when there is no <code nobreak="false">@id</code> attribute;
               this is treated as false.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">filter((), lang("en", ?))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $sequence := (1, 1, 2, 3, 4, 4, 5)
return filter(
  $sequence,
  fn($item, $pos) { $item = $sequence[$pos - 1] }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 4</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-fold-left"><head>fn:fold-left</head><glist><gitem><label>Summary</label><def><p>Processes the supplied sequence from left to right, applying the supplied function
            repeatedly to each item in turn, together with an accumulated result value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="fold-left" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="init" type="item()*"/><arg name="action" type="fn(item()*, item()) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$input</code> is empty, the function returns <code nobreak="false">$init</code>.</p><p>If <code nobreak="false">$input</code> contains at least one item, the function calls 
            <code nobreak="false">$action($init, $input[1])</code>, returning a value <var>A1</var>.</p><p>If <code nobreak="false">$input</code> contains a second item, the function then calls 
            <code nobreak="false">$action(<var>A1</var>, $input[2])</code>, returning <var>A2</var>; to process the <var>n</var>th
         item it calls <code nobreak="false">$action(<var>A/n-1</var>, $input[<var>N</var>])</code>.</p><p>This continues in the same way until the end of the <code nobreak="false">$input</code> sequence; the final result is
         the result of the last call on <code nobreak="false">$action</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function delivers the same result as the following XQuery implementation.</p><eg xml:space="preserve">declare function fold-left(
  $input  as item()*,
  $init   as item()*,
  $action as function(item()*, item()) as item()*
) as item()* {
  if (empty($input)) 
  then $init
  else fold-left(tail($input), $action($init, head($input)), $action)
};</eg></def></gitem><gitem><label>Error Conditions</label><def><p>As a consequence of the function signature and the function calling rules, a type error
            occurs if the supplied function <code nobreak="false">$action</code> cannot be applied to two arguments, where
            the first argument is either the value of <code nobreak="false">$init</code> or the result of a previous
            application of <code nobreak="false">$action</code>, and the second 
            is any single item from the sequence <code nobreak="false">$input</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>This operation is often referred to in the functional programming literature as
            “folding” or “reducing” a sequence. It typically takes a function that operates on a pair of
            values, and applies it repeatedly, with an accumulated result as the first argument, and
            the next item in the sequence as the second argument. The accumulated result is
            initially set to the value of the <code nobreak="false">$init</code> argument, which is conventionally a
            value (such as zero in the case of addition, one in the case of multiplication, or a
            zero-length string in the case of string concatenation) that causes the function to
            return the value of the other argument unchanged.</p><p>Unlike other functions that apply a user-supplied callback function to successive
         items in a sequence, this function does not supply the current position to the callback function
         as an optional argument. If positional information is required, this can be achieved by
         first forming the sequence <code nobreak="false">$input ! { 'position': position(), 'item': . }</code>
         and then applying the <function>fn:fold-left</function> function to this sequence.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-left(
  1 to 5,
  0,
  fn($a, $b) { $a + $b }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">15</eg><p><emph>(This returns the sum of the items in the sequence).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-left(
  (2, 3, 5, 7),
  1,
  fn($a, $b) { $a * $b }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">210</eg><p><emph>(This returns the product of the items in the sequence).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-left(
  (true(), false(), false()),
  false(),
  fn($a, $b) { $a or $b }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(This returns <code nobreak="false">true</code> if any item in the sequence has an effective boolean
                  value of <code nobreak="false">true</code>).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-left(
  (true(), false(), false()),
  false(),
  fn($a, $b) { $a and $b }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg><p><emph>(This returns <code nobreak="false">true</code> only if every item in the sequence has an effective
                  boolean value of <code nobreak="false">true</code>).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-left(
  1 to 5,
  (),
  fn($a, $b) { $b, $a }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">5, 4, 3, 2, 1</eg><p><emph>(This reverses the order of the items in a sequence).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-left(
  1 to 5,
  "",
  concat(?, ".", ?)
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">".1.2.3.4.5"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-left(
  1 to 5,
  "$z",
  concat("$f(", ?, ", ", ?, ")")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"$f($f($f($f($f($z, 1), 2), 3), 4), 5)"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-left(
  1 to 5,
  {},
  fn($map, $n) { map:put($map, $n, $n * 2) }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 1: 2, 2: 4, 3: 6, 4: 8, 5: 10 }</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-fold-right"><head>fn:fold-right</head><glist><gitem><label>Summary</label><def><p>Processes the supplied sequence from right to left, applying the supplied function
            repeatedly to each item in turn, together with an accumulated result value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="fold-right" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="init" type="item()*"/><arg name="action" type="fn(item(), item()*) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$input</code> is empty, the function returns <code nobreak="false">$init</code>.</p><p>Let <var>I/n</var> be the last item in <code nobreak="false">$input</code>, and let <var>A/n</var> be <code nobreak="false">$init</code>.
            The function starts by calling <code nobreak="false">$action(<var>I/n</var>, $init)</code>, producing
         a result <var>A/n-1</var>.</p><p>If there is a previous item, <var>I/n-1</var>,
            the function then calls <code nobreak="false">$action(<var>I/n-1</var>, <var>A/n-1</var>)</code>, producing
            the result <var>A/n-2</var>.</p><p>This continues in the same way until the start of the <code nobreak="false">$input</code> sequence is reached; the final result is
         the value <var>A/0</var>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function delivers the same result as the following XQuery implementation.</p><eg xml:space="preserve">declare function fold-right(
  $input  as item()*,
  $init   as item()*,
  $action as function(item(), item()*) as item()*
) as item()* {
  if (empty($input))
  then $init
  else $action(head($input), fold-right(tail($input), $init, $action))
};</eg></def></gitem><gitem><label>Error Conditions</label><def><p>As a consequence of the function signature and the function calling rules, a type error
            occurs if the supplied function <code nobreak="false">$action</code> cannot be applied to two arguments, where
            the first argument is any item in the sequence <code nobreak="false">$input</code>, and the second is either
            the value of <code nobreak="false">$init</code> or the result of a previous application of
            <code nobreak="false">$action</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>This operation is often referred to in the functional programming literature as
            “folding” or “reducing” a sequence. It takes a function that operates on a pair of
            values, and applies it repeatedly, with the next item in the sequence as the first
            argument, and the result of processing the remainder of the sequence as the second
            argument. The accumulated result is initially set to the value of the <code nobreak="false">$init</code>
            argument, which is conventionally a value (such as zero in the case of addition, one in
            the case of multiplication, or a zero-length string in the case of string concatenation)
            that causes the function to return the value of the other argument unchanged.</p><p>In cases where the function performs an associative operation on its two arguments (such
            as addition or multiplication), <function>fn:fold-right</function> produces the same result as
               <function>fn:fold-left</function>.</p><p>Unlike other functions that apply a user-supplied callback function to successive
         items in a sequence, this function does not supply the current position to the callback function
         as an optional argument. If positional information is required, this can be achieved by
         first forming the sequence <code nobreak="false">$input ! { 'position': position(), 'item': . }</code>
         and then applying the <function>fn:fold-right</function> function to this sequence.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-right(
  1 to 5,
  0,
  fn($a, $b) { $a + $b }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">15</eg><p><emph>(This returns the sum of the items in the sequence).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-right(
  1 to 5,
  "",
  concat(?, ".", ?)
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"1.2.3.4.5."</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">fold-right(
  1 to 5,
  "$z",
  concat("$f(", ?, ", ", ?, ")")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"$f(1, $f(2, $f(3, $f(4, $f(5, $z)))))"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-for-each"><head>fn:for-each</head><changes><change issue="516" PR="828" date="2023-11-14">The <code nobreak="false">$action</code> callback function accepts an optional position argument.</change></changes><glist><gitem><label>Summary</label><def><p>Applies the function item <code nobreak="false">$action</code> to every item from the sequence <var>$input</var>
            in turn, returning the concatenation of the resulting sequences in order.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="for-each" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="action" type="fn(item(), xs:integer) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function calls <code nobreak="false">$action($item, $pos)</code> for each item in <code nobreak="false">$input</code>,
            where <code nobreak="false">$item</code> is the item in question and <code nobreak="false">$pos</code> is its 1-based
            ordinal position in <code nobreak="false">$input</code>. The final result is the sequence concatenation
            of the result of these calls, preserving order.
         </p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function is defined as follows, making use of primitive constructors and accessors defined
		in <bibref ref="xpath-datamodel-40"/>.</p><eg xml:space="preserve">dm:iterate-sequence($input, $action)</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">for-each(1 to 5, fn($a) { $a * $a })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 4, 9, 16, 25</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">for-each(
  ("john", "jane"),
  string-to-codepoints#1
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">106, 111, 104, 110, 106, 97, 110, 101</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">for-each(("23", "29"), xs:int#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">23, 29</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">for-each(
  ('one', 'two', 'three'),
  fn($item, $pos) { $pos || '. ' || $item }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"1. one", "2. two", "3. three"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-for-each-pair"><head>fn:for-each-pair</head><changes><change issue="516" PR="828" date="2023-11-14">The <code nobreak="false">$action</code> callback function accepts an optional position argument.</change></changes><glist><gitem><label>Summary</label><def><p>Applies the function item <code nobreak="false">$action</code> to successive pairs of items taken one from
               <code nobreak="false">$input1</code> and one from <code nobreak="false">$input2</code>, returning the concatenation of the
            resulting sequences in order.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="for-each-pair" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input1" type="item()*"/><arg name="input2" type="item()*"/><arg name="action" type="fn(item(), item(), xs:integer) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the value of the expression:</p><eg xml:space="preserve">
for $pos in 1 to min((count($input1), count($input2)))
return $action($input1[$pos], $input2[$pos], $pos)
</eg></def></gitem><gitem><label>Notes</label><def><note><p>If one sequence is longer than the other, excess items in the longer sequence are ignored.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">for-each-pair(
  ("a", "b", "c"),
  ("x", "y", "z"),
  concat#2
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"ax", "by", "cz"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">for-each-pair(
  1 to 5,
  1 to 5,
  fn($a, $b) { 10 * $a + $b }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">11, 22, 33, 44, 55</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $s := 1 to 8
return for-each-pair($s, tail($s), fn($a, $b) { $a * $b })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2, 6, 12, 20, 30, 42, 56</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
for-each-pair(
  (1, 8, 2),
  (3, 4, 3),
  fn($item1, $item2, $pos) {
    $pos || ': ' || max(($item1, $item2))
  }
)
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"1: 3", "2: 8", "3: 3"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-highest" diff="add" at="A"><head>fn:highest</head><changes><change date="2022-09-20">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a value that is greater than or equal to every other value appearing in the input sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="highest" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/><arg name="key" type="(fn(item()) as xs:anyAtomicType*)?" default="fn:data#1" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>The second argument, <code nobreak="false">$collation</code>, defaults to <code nobreak="false">()</code>.</p><p>Supplying an empty
            sequence as <code nobreak="false">$collation</code> is equivalent to supplying 
            <code nobreak="false">fn:default-collation()</code>. For more
            information on collations see <specref ref="choosing-a-collation"/>.</p><p>The third argument, <code nobreak="false">$key</code>, defaults to the function <code nobreak="false">data#1</code>.</p><p>Let <code nobreak="false">$modified-key</code> be the function:</p><eg xml:space="preserve">fn($item) {
  $key($item) =&gt; data() ! (
    if (. instance of xs:untypedAtomic) then xs:double(.) else .
  )
}</eg><p>That is, the supplied function for computing key values is wrapped in a function that
            converts any <code nobreak="false">xs:untypedAtomic</code> values in its result to <code nobreak="false">xs:double</code>. This makes
            the function consistent with the behavior of <function>fn:min</function> and <function>fn:max</function>,
            but inconsistent with <function>fn:sort</function>, which treats untyped values as strings.</p><p>The result of the function is obtained as follows:</p><ulist><item><p>If the input is an empty sequence, the result is an empty sequence.</p></item><item><p>The input sequence is sorted, by applying the function 
                  <code nobreak="false">fn:sort($input, $collation, $modified-key)</code>.</p></item><item><p>Let <var>$C</var> be the selected collation, or the default collation where applicable.</p></item><item><p>Let <var>$B</var> be the last item in the sorted sequence.</p></item><item><p>The function returns those items <var>$A</var> from the input sequence 
                  that are <termref def="dt-contextually-equal"/> to <code nobreak="false">$B</code>, 
                  retaining their order.
               </p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>If the set of computed keys contains <code nobreak="false">xs:untypedAtomic</code> values that are not 
            castable to <code nobreak="false">xs:double</code> then the
            operation will fail with a dynamic error (<xerrorref spec="FO" class="RG" code="0001"/>).
         </p><p>If the set of computed keys contains values that are not comparable using 
            the <code nobreak="false">lt</code> operator then the sort 
            operation will fail with a type error (<xerrorref spec="XP" class="TY" code="0004"/>).
         </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;a x="10" y="5" z="2"/&gt;</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">highest($e/@*) ! name()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"x"</code></p><p><emph>(By default, untyped values are compared as numbers.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">highest($e/@*, (), string#1) ! name()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"y"</code></p><p><emph>(Here, the attribute values are compared as strings.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">highest(("red", "green", "blue"), (), string-length#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"green"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">highest(
  ("red", "green", "blue"),
  key := {
    "red"  : xs:hexBinary('FF0000'),
    "green": xs:hexBinary('008000'),
    "blue" : xs:hexBinary('0000FF')
  }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"red"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">highest(
  ("red", "orange", "yellow", "green", "blue", "indigo", "violet"),
  key := string-length#1
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"orange", "yellow", "indigo", "violet"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">highest(1 to 25, (), fn { . idiv 10 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">20, 21, 22, 23, 24, 25</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">highest(//employee, (), fn { xs:decimal(salary) })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The employees having the highest salary.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-index-where" diff="add" at="A"><head>fn:index-where</head><changes><change date="2022-09-20">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Returns the positions in an input sequence of items that match a supplied predicate.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="index-where" return-type="xs:integer*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="predicate" type="fn(item(), xs:integer) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The result of the function is a sequence of integers, in monotonic ascending order, representing
            the 1-based positions in the input sequence of those items for which the supplied predicate function
            returns <code nobreak="false">true</code>. A return value of <code nobreak="false">()</code> from the predicate function
         is treated as <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">for-each(
  $input,
  fn($item, $pos) { if ($predicate($item, $pos)) { $pos } }
)</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">index-where((), boolean#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">index-where((0, 4, 9), boolean#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2, 3</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">index-where(1 to 10, fn { . mod 2 = 0 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2, 4, 6, 8, 10</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">index-where(
  ("January", "February", "March", "April", "May", "June",
   "July", "August", "September", "October", "November", "December"),
  contains(?, "r")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 2, 3, 4, 9, 10, 11, 12</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">index-where(
  ( 1, 8, 2, 7, 3 ),
  fn($item, $pos) { $item &lt; 5 and $pos &gt; 2 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">3, 5</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-lowest" diff="add" at="A"><head>fn:lowest</head><changes><change date="2022-09-20">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns those items from a supplied sequence that have the lowest value of a sort key, where
            the sort key can be computed using a caller-supplied function.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="lowest" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/><arg name="key" type="(fn(item()) as xs:anyAtomicType*)?" default="fn:data#1" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>Let <code nobreak="false">$modified-key</code> be the function:</p><eg xml:space="preserve">fn($item) {
  $key($item) =&gt; data() ! (
    if (. instance of xs:untypedAtomic) then xs:double(.) else .
  )
}</eg><p>That is, the supplied function for computing key values is wrapped in a function that
            converts any <code nobreak="false">xs:untypedAtomic</code> values in its result to <code nobreak="false">xs:double</code>. This makes
            the function consistent with the behavior of <function>fn:min</function> and <function>fn:max</function>,
            but inconsistent with <function>fn:sort</function>, which treats untyped values as strings.</p><p>The result of the function is obtained as follows:</p><ulist><item><p>If the input is the empty sequence, the result is the empty sequence.</p></item><item><p>The input sequence is sorted, by applying the function 
                  <code nobreak="false">fn:sort($input, $collation, $modified-key)</code>.</p></item><item><p>Let <var>$C</var> be the selected collation, or the default collation where applicable.</p></item><item><p>Let <var>$B</var> be the first item in the sorted sequence.</p></item><item><p>The function returns those items <var>$A</var> from the input sequence 
                  that are <termref def="dt-contextually-equal"/> to <code nobreak="false">$B</code>, 
                  retaining their order.
               </p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>If the set of computed keys contains <code nobreak="false">xs:untypedAtomic</code> values that are not 
            castable to <code nobreak="false">xs:double</code> then the
            operation will fail with a dynamic error (<xerrorref spec="FO" class="RG" code="0001"/>).
         </p><p>If the set of computed keys contains values that are not comparable using 
            the <code nobreak="false">lt</code> operator then the sort 
            operation will fail with a type error (<xerrorref spec="XP" class="TY" code="0004"/>).
         </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;a x="10" y="5" z="2"/&gt;</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">lowest($e/@*) ! name()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"z"</code></p><p><emph>(By default, untyped values are compared as numbers.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">lowest($e/@*, (), string#1) ! name()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"x"</code></p><p><emph>(Here, the attribute values are compared as strings.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">lowest(("red", "green", "blue"), (), string-length#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"red"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">lowest(
  ("red", "green", "blue"),
  key := {
    "red"  : xs:hexBinary('FF0000'),
    "green": xs:hexBinary('008000'),
    "blue" : xs:hexBinary('0000FF')
  }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"blue"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">lowest(
  ("April", "June", "July", "August"),
  key := string-length#1
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"June", "July"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">lowest(1 to 25, (), fn { . idiv 10 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2, 3, 4, 5, 6, 7, 8, 9</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">lowest(//employee, (), fn { xs:decimal(salary) })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The employees having the lowest salary.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-partial-apply"><head>fn:partial-apply</head><changes><change issue="1816" PR="1825" date="2025-02-25">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Performs partial application of a function item by binding values to selected arguments.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="partial-apply" return-type="fn(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="function" type="fn(*)"/><arg name="arguments" type="map(xs:positiveInteger, item()*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The result is a function obtained by binding values to selected arguments of 
            the function item <code nobreak="false">$function</code>. The arguments to be bound are represented
            by entries in the <code nobreak="false">$arguments</code> map: an entry with key <code nobreak="false">$i</code>
            and value <code nobreak="false">$v</code> causes the argument at position <code nobreak="false">$i</code> (1-based)
            to be bound to <code nobreak="false">$v</code>.
         </p><p>Any entries in <code nobreak="false">$arguments</code> whose keys are greater than the arity of
         <code nobreak="false">$function</code> are ignored.</p><p>If <code nobreak="false">$arguments</code> is the empty map then the function returns <code nobreak="false">$function</code>
         unchanged.</p><p>For example, the effect of calling <code nobreak="false">fn:partial-apply($f, { 2: $x })</code>
            is the same as the effect of the partial 
            appplication <code nobreak="false">$f(?, $x, ?, ?, ....)</code>. 
            The coercion rules are applied to the supplied arguments
            in the usual way.</p><p>Unlike a partial application using place-holder arguments:</p><ulist><item><p>The arity of <code nobreak="false">$function</code> need not be statically known.</p></item><item><p>It is possible to bind all the arguments of <code nobreak="false">$function</code>: the effect
               is to return a zero-arity function.
          </p></item></ulist><p>The result is a <xtermref spec="XP40" ref="dt-partially-applied-function">partially applied function</xtermref> having
                        the following properties (which are defined in <xspecref spec="DM40" ref="function-items"/>):
                     </p><ulist><item><p><term>name</term>: absent.
                           </p></item><item><p><term>identity</term>: A new function
                           identity distinct from the identity of any other function item.</p><note><p>See also <xspecref spec="XP40" ref="id-function-identity"/>.</p></note></item><item><p><term>arity</term>: The arity of <code nobreak="false">$function</code> minus the
                              number of parameters in <code nobreak="false">$function</code> that map to supplied
                              arguments in <code nobreak="false">$arguments</code>.</p></item><item><p>
                              <term>parameter names</term>:
                              The names of the parameters of <code nobreak="false">$function</code>
                              that do not map to supplied
                              arguments in <code nobreak="false">$arguments</code>.
                           </p></item><item><p>
                              <term>signature</term>: The parameters in the returned function
                              are the parameters of <code nobreak="false">$function</code>
                              that do not map to supplied
                              arguments in <code nobreak="false">$arguments</code>,
                              retaining order. The result type of the returned function
                              is the same as the result type of <code nobreak="false">$function</code>.</p><p>An implementation that can determine a more specific signature (for example, 
                              through use of type analysis) is permitted to do so.
                           </p></item><item><p><term>body</term>: The body of <code nobreak="false">$function</code>.</p></item><item><p>
                              <term>captured context</term>: The
                              static and dynamic context of <code nobreak="false">$function</code>, augmented,
                              for each supplied argument, with
                              a binding of the converted argument value
                              to the corresponding parameter name.
                           </p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>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.</p><p>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).</p></def></gitem><gitem><label>Notes</label><def><note><p>See also <xspecref spec="XP40" ref="id-partial-function-application"/>.</p><p>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.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $f := partial-apply(dateTime#2,  {2: xs:time('00:00:00') })
return $f(xs:date('2025-03-01'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2025-03-01T00:00:00')</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-partition" diff="add" at="A"><head>fn:partition</head><changes><change issue="125" PR="507" date="2023-05-19">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Partitions 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.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="partition" return-type="array(item()*)*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="split-when" type="fn(item()*, item(), xs:integer) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function starts by creating a partition containing the first item in the input sequence,
            if any. For each remaining item <var>J</var> in the input sequence,
            other than the first, it calls the supplied <code nobreak="false">$split-when</code> function with three 
            arguments: the contents of the current partition, the item <var>J</var>, and the current
            position in the input sequence.</p><p>Each partition is a sequence of items; the function result wraps each partition as an array, and returns
            the sequence of arrays.</p><p>If the <code nobreak="false">$split-when</code> function returns <code nobreak="false">true</code>, the current partition is wrapped as an array and added to the result,
            and a new current partition is created, initially containing the item <var>J</var> only. If the <code nobreak="false">$split-when</code> 
            function returns <code nobreak="false">false</code> or <code nobreak="false">()</code>, the item <var>J</var> is added to the current partition.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">for-each(
  $input,
  fn($item, $pos) { { 'item': $item, 'pos': $pos } }
)
=&gt; fold-left((), fn($partitions, $pair) {
  if (empty($partitions) or $split-when(foot($partitions)?*, $pair?item, $pair?pos))
  then ($partitions, [ $pair?item ])
  else (trunk($partitions), array { foot($partitions)?*, $pair?item })
})</eg></def></gitem><gitem><label>Notes</label><def><note><p>The function enables a variety of positional grouping problems to be solved. For example:</p><ulist><item><p><code nobreak="false">partition($input, fn($a, $b) { count($a) eq 3 }</code>
               partitions a sequence into fixed size groups of length 3.</p></item><item><p><code nobreak="false">partition($input, fn($a, $b) { boolean($b/self::h1) }</code>
               starts a new group whenever an <code nobreak="false">h1</code> element is encountered.</p></item><item><p><code nobreak="false">partition($input, fn($a, $b) { $b lt foot($a) }</code>
               starts a new group whenever an item is encountered whose value is less than
               the value of the previous item.</p></item></ulist><p>The callback function is not called to process the first item in the input sequence, because this will
            always start a new partition. The first argument to the callback function (the current partition) is always
            a non-empty sequence.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">partition(
  ("Anita", "Anne", "Barbara", "Catherine", "Christine"), 
  fn($partition, $next) {
    substring(head($partition), 1, 1) ne substring($next, 1, 1)
  }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "Anita", "Anne" ], [ "Barbara" ], [ "Catherine", "Christine" ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">partition(
  (1, 2, 3, 4, 5, 6, 7),
  fn($partition, $next) { count($partition) eq 2 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">partition(
  (1, 4, 6, 3, 1, 1),
  fn($partition, $next) { sum($partition) ge 5 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, 4 ], [ 6 ], [ 3, 1, 1 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">partition(
  tokenize("In the beginning was the word"), 
  fn($partition, $next) {
    sum(($partition, $next) ! string-length()) gt 10
  }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "In", "the" ], [ "beginning" ], [ "was", "the", "word" ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">partition(
  (1, 2, 3, 6, 7, 9, 10),
  fn($partition, $next) { $next != foot($partition) + 1 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, 2, 3 ], [ 6, 7 ], [ 9, 10 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">partition(
  ('a', 'b', 'c', 'd', 'e'),
  fn($all, $next, $p) { $p mod 2 = 1 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "a", "b" ], [ "c", "d" ], [ "e" ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-scan-left" diff="add" at="A"><head>fn:scan-left</head><changes><change issue="982" PR="1296" date="2024-06-23">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Produces the sequence of successive partial results from 
           the evaluation of <function>fn:fold-left</function> with the same arguments.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="scan-left" return-type="array(*)*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="init" type="item()*"/><arg name="action" type="fn(item()*, item()) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence of <var>N</var>+1 
            <xtermref spec="DM40" ref="dt-single-member-array">single-member arrays</xtermref>, where <var>N</var> is the number of 
         items in <code nobreak="false">$input</code>. For values of <code nobreak="false">$n</code> in the range 0 to <var>N</var>,
            the value of the single member of array <code nobreak="false">$n+1</code> in the result sequence is the value of the expression
            <code nobreak="false">fold-left( subsequence($input, 1, $n), $init, $action )</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">(0 to count($input)) 
! [fold-left(subsequence($input, 1, .), $init, $action) ]</eg></def></gitem><gitem><label>Notes</label><def><note><p>A practical implementation is likely to compute each array in the result sequence based on the value
         of the previous item, rather than computing each item independently as implied by the specification.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">scan-left(1 to 5, 0, op('+'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 0 ], [ 1 ], [ 3 ], [ 6 ], [ 10 ], [ 15 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">scan-left(1 to 3, 0, op('-'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 0 ], [ -1 ], [ -3 ], [ -6 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">scan-left(1 to 5, 1, op('*'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1 ], [ 1 ], [ 2 ], [ 6 ], [ 24 ], [ 120 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">scan-left(1 to 3, (), fn($a, $b) { $b, $a })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ () ], [ 1 ], [ (2, 1) ], [ (3, 2, 1) ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-scan-right" diff="add" at="A"><head>fn:scan-right</head><changes><change>New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Produces the sequence of successive partial results from 
           the evaluation of <function>fn:fold-right</function> with the same arguments.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="scan-right" return-type="array(*)*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="init" type="item()*"/><arg name="action" type="fn(item(), item()*) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence of <var>N</var>+1 
            <xtermref spec="DM40" ref="dt-single-member-array">single-member arrays</xtermref>, where <var>N</var> is the number of 
         items in <code nobreak="false">$input</code>. For values of <code nobreak="false">$n</code> in the range 0 to <var>N</var>,
            the value of the single member of array <code nobreak="false">$n+1</code> in the result sequence is the value of the expression
            <code nobreak="false">fold-right( subsequence($input, count($input)-$n+1), $init, $action )</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">(0 to count($input)) 
! [ fold-right(subsequence($input, count($input)-.+1), $init, $action) ]</eg></def></gitem><gitem><label>Notes</label><def><note><p>A practical implementation is likely to compute each array in the result sequence based on the value
         of the previous item, rather than computing each item independently as implied by the specification.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">scan-right(1 to 10, 0, op('+'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 55 ], [ 54 ], [ 52 ], [ 49 ], [ 45 ], [ 40 ],
[ 34 ], [ 27 ], [ 19 ], [ 10 ], [ 0 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">scan-right(1 to 3, 0, op('-'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 2 ], [ -1 ], [ 3 ], [ 0 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">scan-right(1 to 5, (), fn($a, $b) { $b, $a })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ (5, 4, 3, 2, 1) ], [ (5, 4, 3, 2) ], [ (5, 4, 3) ],
[ (5, 4) ], [ 5 ], [ () ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-some" diff="add" at="A"><head>fn:some</head><changes><change date="2022-09-13">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if at least one item in the input sequence matches a supplied predicate.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="some" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="predicate" type="(fn(item(), xs:integer) as xs:boolean?)?" default="fn:boolean#1" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns true if (and only if) there is an item <code nobreak="false">$item</code> at position <code nobreak="false">$pos</code>
            in the input sequence such that <code nobreak="false">$predicate($item, $pos)</code> returns true.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">exists(filter($input, $predicate))</eg></def></gitem><gitem><label>Error Conditions</label><def><p>An error is raised if the <code nobreak="false">$predicate</code> function raises an error. In particular,
         when the default predicate <code nobreak="false">fn:boolean#1</code> is used, an error is raised if an
         item has no effective boolean value.</p></def></gitem><gitem><label>Notes</label><def><note><p>It is possible for the supplied <code nobreak="false">$predicate</code> to be a function whose arity is less than two.
            The coercion rules mean that the additional parameters are effectively ignored. Frequently a predicate
            function will only consider the item itself, and disregard its position in the sequence.</p><p>The predicate is required to return either <code nobreak="false">true</code>, <code nobreak="false">false</code>, or the empty
            sequence (which is treated as <code nobreak="false">false</code>). A predicate such as <code nobreak="false">fn { self::h1 }</code>
            results in a type error because it returns a node, not a boolean.</p><p>The implementation <rfc2119>may</rfc2119> deliver a result as soon as one item is found for which the predicate
         returns <code nobreak="false">true</code>; it is not required to evaluate the predicate for every item,
         nor is it required to examine items sequentially from left to right.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">some(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">some((1 = 1, 2 = 2, 3 = 4))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">some((), boolean#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">some((1, 3, 7), fn { . mod 2 = 1 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">some(-5 to +5, fn { . ge 0 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">some(
  ("January", "February", "March", "April",
   "September", "October", "November", "December"),
  contains(?, "z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">some(
  ("January", "February", "March", "April",
   "September", "October", "November", "December")
  =!&gt; contains("r")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">some(("", 0, number('NaN')))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p><p><emph>(The effective boolean value in each case is false.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">some(reverse(1 to 5), fn($num, $pos) { $num = $pos })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-sort"><head>fn:sort</head><glist><gitem><label>Summary</label><def><p>Sorts a supplied sequence, based on the value of a sort key supplied as a function.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="sort" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/><arg name="key" type="fn(item()) as xs:anyAtomicType*" default="fn:data#1" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>This function is retained for compatibility from version 3.1 of this specification. Version 4.0
         introduces two more powerful functions, <function>fn:sort-by</function> and <function>fn:sort-with</function>.</p><p>The function call <code nobreak="false">fn:sort($input, $collation, $key)</code> is defined to have the same effect as the
         call <code nobreak="false">fn:sort-by($input, { 'key': $key, 'collation': $collation, 'order': 'ascending'})</code>.
         See <function>fn:sort-by</function>.</p><p>The result of the function is a sequence that contains all the items from <code nobreak="false">$input</code>,
         typically in a different order, the order being defined by the supplied sort key definitions.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">fn:sort-by($input, { 'key':$key, 'collation':$collation, 'order':'ascending' })</eg></def></gitem><gitem><label>Error Conditions</label><def><p>If the set of computed sort keys contains values that are not comparable using the <code nobreak="false">lt</code> operator then the sort 
            operation will fail with a type error (<xerrorref spec="XP" class="TY" code="0004"/>).
         </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sort((1, 4, 6, 5, 3))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 3, 4, 5, 6</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sort((1, -2, 5, 10, -10, 10, 8), (), abs#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, -2, 5, 8, 10, -10, 10</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $SWEDISH := collation({ 'lang': 'se' })
return sort(//name!string(), $SWEDISH)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The names in <code nobreak="false">//name</code> sorted using Swedish collation.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">sort(//employee, (), fn { name ! (last, first) })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>A sorted sequence of employees by last name as the major sort key and first name as the minor sort key,
               using the default collation.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-sort-by"><head>fn:sort-by</head><changes><change issue="1085" PR="2001" date="2025-05-19">New in 4.0.</change></changes><glist><gitem><label>Summary</label><def><p>Sorts a supplied sequence, based on the value of a number of sort keys supplied as functions.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="sort-by" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="keys" type="record(key? as (fn(item()) as xs:anyAtomicType*)?, collation? as xs:string?, order? as enum('ascending', 'descending')?)*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>The result of the function is a sequence that contains all the items from <code nobreak="false">$input</code>,
         typically in a different order, the order being defined by the supplied <term>sort key definitions</term>.</p><p>A <term>sort key definition</term> is a record with three parts:</p><olist><item><p><code nobreak="false">key:</code> A <term>sort key function</term>, which is applied to each item in the input sequence to
            determine a <term>sort key value</term>. If no function is supplied, the default is <code nobreak="false">fn:data#1</code>,
            which atomizes the item.</p></item><item><p><code nobreak="false">collation:</code> A <term>collation</term>, which is used when comparing <term>sort key values</term>
               that are of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>. If no collation is supplied, the default
               collation from the static context is used.</p><p>When comparing values of types other than <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>,
               the collation is ignored (but an error <rfc2119>may</rfc2119> be reported if it is
               invalid). For more information see <specref ref="choosing-a-collation"/>.</p></item><item><p><code nobreak="false">order:</code> An <term>order direction</term>, either <code nobreak="false">"ascending"</code> or
            <code nobreak="false">"descending"</code>. The default is <code nobreak="false">"ascending"</code>.</p></item></olist><p>The number of sort key definitions is determined by the number of records supplied
            in the <code nobreak="false">$keys</code> argument. If the argument is absent or empty, the default is
            a single sort key definition using the function <code nobreak="false">data#1</code>, using the default collation
            from the static context, and with order <code nobreak="false">ascending</code>.</p><p>The result of the <code nobreak="false">fn:sort-by</code> function is obtained as follows:</p><olist><item><p>The result sequence contains the same items as the input sequence <code nobreak="false">$input</code>, 
                  but generally in a different order.</p></item><item><p>The sort key definitions are established as described above.
                  The sort key definitions are in major-to-minor order. That is, the position of two
                  items <code nobreak="false">$A</code> and <code nobreak="false">$B</code> in the result sequence is determined first by the 
                  relative magnitude of their
                  primary sort key values, which are computed by evaluating the <term>sort key function</term> in the 
                  first sort key definition.
                  If those two sort key values are equal, then the position is determined by the relative magnitude
                  of their secondary sort key values, computed by evaluating the 
                  sort key function in the second sort key definition, and so on.</p></item><item><p>When a pair of corresponding sort key values of <code nobreak="false">$A</code> and <code nobreak="false">$B</code> are 
                  found to be not equal,
                  then <code nobreak="false">$A</code> precedes <code nobreak="false">$B</code> in the result sequence 
                  if both the following conditions are true, or if both conditions are false:</p><olist><item><p>The sort key value for <code nobreak="false">$A</code> is less than the sort key value for <code nobreak="false">$B</code>,
                           as defined below.</p></item><item><p>The <term>order direction</term> in the corresponding sort key definition
                        is <code nobreak="false">"ascending"</code>.</p></item></olist></item><item><p>If all the sort key values for <code nobreak="false">$A</code> and <code nobreak="false">$B</code> are pairwise equal, then 
               <code nobreak="false">$A</code> precedes <code nobreak="false">$B</code> in the result sequence if and only if
               <code nobreak="false">$A</code> precedes <code nobreak="false">$B</code> in the input sequence.</p><note><p>That is, the sort is <emph>stable</emph>.</p></note></item><item><p>Each sort key value for a given item is obtained by applying the sort key
               function of the corresponding sort key definition to that item. The result
               of this function is in the general case a sequence of atomic items.
               Two sort key values <code nobreak="false">$a</code> and <code nobreak="false">$b</code> are compared as follows:</p><olist><item><p>Let <var>$C</var> be the collation in the corresponding
                     sort key definition.</p></item><item><p>Let <code nobreak="false">$REL</code> be the result of evaluating <code nobreak="false">op:lexicographic-compare($key($A), $key($B), $C)</code>
                     where <code nobreak="false">op:lexicographic-compare($a, $b, $C)</code> is defined as follows:</p><eg xml:space="preserve">if (empty($a) and empty($b)) then 0 
else if (empty($a)) then -1
else if (empty($b)) then +1
else let $rel = op:simple-compare(head($a), head($b), $C)
     return if ($rel eq 0)
            then op:lexicographic-compare(tail($a), tail($b), $C)
            else $rel</eg></item><item><p>Here <code nobreak="false">op:simple-compare($k1, $k2)</code> is defined as follows:</p><eg xml:space="preserve">if ($k1 instance of (xs:string | xs:anyURI | xs:untypedAtomic)
    and $k2 instance of (xs:string | xs:anyURI | xs:untypedAtomic))
then compare($k1, $k2, $C)
else if ($k1 instance of xs:numeric and $k2 instance of xs:numeric)
then compare($k1, $k2)
else if ($k1 eq $k2) then 0
else if ($k2 lt $k2) then -1
else +1</eg><note><p>This raises an error if two keys are not comparable, for example
                        if one is a string and the other is a number, or if both belong to a non-ordered
                        type such as <code nobreak="false">xs:QName</code>.</p></note></item><item><p>If <code nobreak="false">$REL</code> is zero, then the two sort key values are deemed
                     equal; if <code nobreak="false">$REL</code> is -1 then <code nobreak="false">$a</code> is deemed less than
                     <code nobreak="false">$b</code>, and if <code nobreak="false">$REL</code> is +1 then <code nobreak="false">$a</code> is deemed greater than
                     <code nobreak="false">$b</code></p></item></olist></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>If the set of computed sort keys contains values that are not comparable using the <code nobreak="false">lt</code> operator then the sort 
            operation will fail with a type error (<xerrorref spec="XP" class="TY" code="0004"/>).
         </p></def></gitem><gitem><label>Notes</label><def><note><p>The function is a generalization of the <function>fn:sort</function> function available in 3.1, 
            which is retained for compatibility. The enhancements allow multiple sort keys to be defined, each potentially with
         a different collation, and allow sorting in descending order.</p><p>If the sort key for an item evaluates to the empty sequence, the effect of the rules is that this item
            precedes any value for which the key is non-empty. This is equivalent to the effect of the XQuery option 
            <code nobreak="false">empty least</code>. The effect of the option <code nobreak="false">empty greatest</code> can be achieved by adding an
            extra sort key definition with <code nobreak="false">{ 'key': fn { empty(K(.) } }</code>: when comparing boolean sort keys,
            <code nobreak="false">false</code> precedes <code nobreak="false">true</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sort-by((1, 4, 6, 5, 3), ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 3, 4, 5, 6</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sort-by((1, 4, 4e0, 6, 5, 3), { 'order': 'descending' })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">6, 5, 4, 4e0, 3, 1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sort-by((1, -2, 5, 10, -10, 10, 8), { 'key': abs#1 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, -2, 5, 8, 10, -10, 10</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $SWEDISH := collation({ 'lang': 'se' })
return sort-by(//name, { 'collation': $SWEDISH })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The names in <code nobreak="false">//name</code> sorted using Swedish collation.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">sort-by(//employee, { 'key': fn { name ! (last, first) } })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Sorts a sequence of employees by last name as the major sort key 
                  and first name as the minor sort key,
               using the default collation</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">sort-by(
  //employee, 
  ({ 'key': fn { name/last }, 'collation': collation({ 'lang': 'se' }) },
   { 'key': fn { xs:decimal(salary) }, 'order': 'descending' }))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Sorts a sequence of employees first by increasing last name (using Swedish collation order)
               and then by decreasing salary</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-sort-with" diff="add" at="A"><head>fn:sort-with</head><changes><change issue="655 2012" PR="795 2228" date="2024-02-20">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Sorts a supplied sequence, according to the order induced by the supplied comparator
            functions.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="sort-with" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="comparators" type="(fn(item(), item()) as xs:integer)+"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the items of the supplied <code nobreak="false">$input</code> are sorted into an
            order based on the result of evaluating the supplied <code nobreak="false">$comparators</code>. 
            The result is a sorted sequence.</p><p>Each comparator function takes two items and returns an <code nobreak="false">xs:integer</code> that
            defines the relationship between these items, following the conventions of the
            <function>fn:compare</function> function. Specifically, when a comparator
            <code nobreak="false">$c</code> is used to compare two items <code nobreak="false">$a</code> and <code nobreak="false">$b</code>,
            it must return a negative integer if <code nobreak="false">$a</code> is to be sorted before <code nobreak="false">$b</code>,
            zero if they are considered equal, and a positive integer if <code nobreak="false">$a</code> is
            to be sorted after <code nobreak="false">$b</code>.</p><p>There may be more than one comparator, representing sort keys in major to minor order.
         To determine the relative position of two items <code nobreak="false">$a</code> and <code nobreak="false">$b</code>:</p><olist><item><p>The first comparator is called: <code nobreak="false">$comparators[1]($a, $b)</code>. If
            the result is non-zero, this determines the relative position of <code nobreak="false">$a</code>
               and <code nobreak="false">$b</code> in the result sequence, and any further comparators
            can be ignored.</p></item><item><p>If the <var>N</var>th comparator returns zero, then:</p><olist><item><p>If this is the last comparator, then the two items are considered
                  equal, and their relative position in the result sequence will be the same
                  as their relative position in the input sequence (that is, the sort is
                  <emph>stable</emph>).</p></item><item><p>Otherwise, the next comparator is evaluated, and so on,
                  until the last comparator is reached or the result of a comparator is non-zero.</p></item></olist></item></olist><p>To ensure that the sorting algorithm produces predictable results (indeed, to ensure
         that it terminates), it is necessary for the comparators to have certain properties.
         Specifically, for every comparator <var>C</var>:</p><olist><item><p><var>C</var> must be deterministic (if called twice with the same arguments,
            it must deliver the same result).</p></item><item><p>Every item must be equal to itself: <code nobreak="false"><var>C</var>($a, $a)</code> must be zero.</p></item><item><p>The ordering must be consistent: if <code nobreak="false"><var>C</var>($a, $b) &lt; 0</code>,
            then <code nobreak="false"><var>C</var>($b, $a) &gt; 0</code>, and vice versa, and similarly,
            if <code nobreak="false"><var>C</var>($a, $b) = 0</code>,
            then <code nobreak="false"><var>C</var>($b, $a) = 0</code>.</p></item><item><p>The ordering must be transitive: if <code nobreak="false"><var>C</var>($a, $b) &lt; 0</code>
               and <code nobreak="false"><var>C</var>($b, $c) &lt; 0</code>, then <code nobreak="false"><var>C</var>($a, $c) &lt; 0</code>.</p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>If a comparator function raises an error when processing any pair of items from the input sequence
         (for example, if the comparator function is <code nobreak="false">fn:compare#2</code> and the two items are of
         non-comparable types), then the evaluation of <function>fn:sort-with</function> fails with that
         error.</p><p>In general it is unpredictable which pairs of items from the input sequence
         will actually be compared using each comparator function. However, a comparator function
         <rfc2119>must</rfc2119> not be called to compare two items if they have been determined as unequal by
         an earlier comparator function.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sort-with((1, 4, 6, 5, 3), compare#2)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 3, 4, 5, 6</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sort-with((1, 4, 6, 5, 3), op('-'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 3, 4, 5, 6</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">sort-with((1, 4, 4e0, 6, 5, 3), fn($a, $b) { compare($b, $a) })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">6, 5, 4, 4e0, 3, 1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">sort-with(
  (1, -2, 5, 10, -12, 8),
  fn($a, $b) { abs($a) - abs($b) }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, -2, 5, 8, 10, -12</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $persons := &lt;persons&gt;
  &lt;person name='Josipa' age='8'/&gt;
  &lt;person name='Jade' age='6'/&gt;
  &lt;person name='Jie' age='8'/&gt;
&lt;/persons&gt;
return sort-with($persons/person, (
  fn($a, $b) { compare($a/@age, $b/@age) },
  fn($a, $b) { compare($a/@name, $b/@name) }
))
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;person name="Jade" age="6"/&gt;
&lt;person name="Jie" age="8"/&gt;
&lt;person name="Josipa" age="8"/&gt;</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subsequence-where" diff="add" at="2024-01-10"><head>fn:subsequence-where</head><changes><change issue="878" PR="940" date="2024-02-05">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a contiguous sequence of items from <code nobreak="false">$input</code>, with the start and end
         points located by applying predicates.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="subsequence-where" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="from" type="(fn(item(), xs:integer) as xs:boolean?)?" default="true#0" note="default-on-empty"/><arg name="to" type="(fn(item(), xs:integer) as xs:boolean?)?" default="false#0" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function returns the subsequence of <code nobreak="false">$input</code> starting with the
         first item that matches the <code nobreak="false">$from</code> predicate, and ending with the first subsequent
         item that matches the <code nobreak="false">$to</code> predicate. If <code nobreak="false">$from</code> is <code nobreak="false">true#0</code>,
         it matches for the first item; if <code nobreak="false">$to</code> is <code nobreak="false">false#0</code>, it accepts all
         remaining items. If <code nobreak="false">$from</code> does not match any items in <code nobreak="false">$input</code>,
         the result is the empty sequence; if <code nobreak="false">$to</code> does not match any items, all items up
         to the last are included in the result.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">let $start := index-where($input, $from)[1] otherwise count($input) + 1
let $end   := index-where($input, $to)[. ge $start][1] otherwise count($input) + 1
return slice($input, $start, $end)</eg></def></gitem><gitem><label>Notes</label><def><note><p>The result includes both the item that matches the <code nobreak="false">$from</code> condition
         and the item that matches the <code nobreak="false">$to</code> condition. To select a subsequence that
         starts after the <code nobreak="false">$from</code> item, apply the <function>fn:tail</function> function 
         to the result. To select a subsequence that ends before the <code nobreak="false">$to</code> item,
         apply the <function>fn:trunk</function> function to the result.</p><p>The predicate functions supplied to the <code nobreak="false">$from</code> and <code nobreak="false">$to</code>
         parameters can include an integer position argument as well as the item itself.
         This position will always be 1-based, relative to the start of <code nobreak="false">$input</code>.
         This means it is possible to select items based on their absolute position in the
         <code nobreak="false">$input</code> sequence, but there is no mechanism to select an end position
         relative to the start position. If this is needed, the function can be combined with others:
         for example, to select a subsequence of four items starting with <code nobreak="false">"Barbara"</code>,
         use <code nobreak="false">$input =&gt; subsequence-where(fn { . eq "Barbara" }) =&gt; slice(end := 4)</code>.</p><p>If the requirement is to select all elements stopping before the first <code nobreak="false">h2</code>
            element if it exists, or up to the end of the sequence otherwise, the simplest
         solution is perhaps to write:</p><eg xml:space="preserve">slice($input, end:=index-where($input, fn { boolean(self::h2) })[1])</eg><p>A return value of <code nobreak="false">()</code> from the <code nobreak="false">$from</code> or <code nobreak="false">$to</code>
         predicate is treated as <code nobreak="false">false</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $names := ("Anna", "Barbara", "Catherine", "Delia",  "Eliza", "Freda",
  "Gertrude", "Hilda")</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">subsequence-where($names, starts-with(?, "E"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Eliza", "Freda", "Gertrude", "Hilda"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">subsequence-where($names, to := starts-with(?, "D"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Anna", "Barbara", "Catherine", "Delia"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">subsequence-where($names, to := starts-with(?, "D")) =&gt; trunk()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Anna", "Barbara", "Catherine"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">subsequence-where($names, starts-with(?, "E"), starts-with(?, "G"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Eliza", "Freda", "Gertrude"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">subsequence-where(
  $names,
  starts-with(?, "D"), fn { string-length(.) gt 5 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Delia", "Eliza", "Freda", "Gertrude"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">subsequence-where($names, starts-with(?, "M"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">subsequence-where($names, starts-with(?, "G"), starts-with(?, "Z"))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Gertrude", "Hilda"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">subsequence-where($names)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Anna", "Barbara", "Catherine", "Delia", "Eliza", "Freda",
  "Gertrude", "Hilda"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">subsequence-where(
  $names,
  fn($it, $pos) { ends-with($it, "a") and $pos gt 5 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Freda", "Gertrude", "Hilda"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">subsequence-where(
  $names, 
  to := fn($it, $pos) { ends-with($it, "a") and $pos ge 5 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Anna", "Barbara", "Catherine", "Delia", "Eliza"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-take-while" diff="add" at="2024-02-07"><head>fn:take-while</head><changes><change issue="1002 1038" PR="1046" date="2004-03-05">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Returns items from the input sequence prior to the first one that fails to match a supplied predicate.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="take-while" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="predicate" type="fn(item(), xs:integer) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns all items in the sequence prior to the first one where the result of
         calling the supplied <code nobreak="false">$predicate</code> function, with the current item and its position
         as arguments, returns the value <code nobreak="false">false</code> or <code nobreak="false">()</code>.</p><p>If every item in the sequence satisfies the predicate, then <code nobreak="false">$input</code> is returned
         in its entirety.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XQuery expression.</p><eg xml:space="preserve">for $item at $pos in $input
while $predicate($item, $pos)
return $item</eg></def></gitem><gitem><label>Notes</label><def><note><p>There is no analogous <code nobreak="false">drop-while</code> or <code nobreak="false">skip-while</code> function,
         as found in some functional programming languages. The effect of 
            <code nobreak="false">drop-while($input, $predicate)</code> can be achieved by calling
         <code nobreak="false">fn:subsequence-where($input, fn { not($predicate(.)) })</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">take-while(10 to 20, fn { . le 12 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">10, 11, 12</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">take-while(10 to 20, fn { . lt 100 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">10 to 20</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">take-while((), boolean#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">take-while(
  ("A", "B", "C", " ", "E"), 
  fn { boolean(normalize-space()) }
 )</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"A", "B", "C"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-xml("&lt;doc&gt;&lt;p/&gt;&lt;p/&gt;&lt;h2/&gt;&lt;img/&gt;&lt;p/&gt;&lt;/doc&gt;")/doc/*
=&gt; take-while(fn { boolean(self::p) })
=&gt; count()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
("Aardvark", "Antelope", "Bison", "Buffalo", "Camel", "Dingo")
=&gt; take-while(starts-with(?, "A"))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Aardvark", "Antelope"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">take-while(10 to 20, fn($num, $pos) { $num lt 18 and $pos lt 4 })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">10, 11, 12</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">take-while(
  characters("ABCD-123"), 
  fn($ch, $pos) { $pos lt 4 and $ch ne '-' }
) =&gt; string-join()
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"ABC"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">take-while(
  ("A", "a", "B", "b", "C", "D", "d"),
   fn($ch, $pos) {
     matches($ch, if ($pos mod 2 eq 1) then "\p{Lu}" else "\p{Ll}")
   }
 )
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"A", "a", "B", "b", "C"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-transitive-closure"><head>fn:transitive-closure</head><changes><change issue="518 554 754" PR="521 761" date="2023-10-18">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns all the GNodes reachable from a given start GNode by applying a supplied function repeatedly.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="transitive-closure" return-type="gnode()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="gnode()?"/><arg name="step" type="fn(gnode()) as gnode()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function works with both XNodes and JNodes.</p><p>The value of <code nobreak="false">$node</code> is a node from which navigation starts. If <code nobreak="false">$node</code> is an
         empty sequence, the function returns the empty sequence.
         </p><p>The value of <code nobreak="false">$step</code> is a function that takes a single GNode as input, and returns a set of GNodes as its result.</p><p>The result of the <function>fn:transitive-closure</function> function is the set of GNodes that are reachable from
            <code nobreak="false">$node</code> by applying the <code nobreak="false">$step</code> function one or more times.</p><p>Although <code nobreak="false">$step</code> may return any sequence of GNodes, the result is treated as a set: the order of GNodes
            in the sequence is ignored, and duplicates are ignored. The result of of the
            <code nobreak="false">transitive-closure</code> function will always be a sequence of GNodes in document order with no duplicates.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function delivers the same result as the following XQuery implementation.</p><eg xml:space="preserve">declare %private function tc-inclusive(
  $nodes as gnode()*,
  $step  as fn(gnode()) as gnode()*
) as gnode()* {
  let $nextStep := $nodes/$step(.)
  let $newNodes := $nextStep except $nodes
  return if (exists($newNodes))
         then $nodes union tc-inclusive($newNodes, $step)
         else $nodes
};

declare function transitive-closure (
  $node as gnode(),
  $step as fn(gnode()) as gnode()*
) as gnode()* {
  tc-inclusive($node/$step(.), $step)
};

(: Explanation:

   The private helper function tc-inclusive takes a set of GNodes as input,
   and calls the $step function on each one of those GNodes; if the result 
   includes GNodes that are not already present in the input, then it makes 
   a recursive call to find GNodes reachable from these new GNodes, and returns
   the union of the supplied GNodes and the GNodes returned from the recursive
   call (which will always include the new GNodes selected in the first step).
   
   If there are no new GNodes, the recursion ends, returning the GNodes that 
   have been found up to this point.
   
   The main function fn:transitive-closure finds the nodes that are reachable 
   from the start GNodes in a single step, and then invokes the helper function 
   tc-inclusive to add GNodes that are reachable in multiple steps.
:)</eg></def></gitem><gitem><label>Notes</label><def><note><p>Cycles in the data are not a problem; 
            the function stops searching when it finds no new GNodes.</p><p>The function may fail to terminate if the supplied <code nobreak="false">$step</code> function constructs and returns
         new GNodes. A processor <rfc2119>may</rfc2119> detect this condition but is not required to do so.</p><p>The <code nobreak="false">$node</code> GNodes is not included in the result, unless it is reachable by applying
         the <code nobreak="false">$step</code> function one or more times. If a result is required that does include <code nobreak="false">$node</code>,
         it can be readily added to the result using the union operator:
            <code nobreak="false">$node | transitive-closure($node, $step)</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $data := document { &lt;doc&gt;
  &lt;person id="0"/&gt;
  &lt;person id="1" manager="0"/&gt;
  &lt;person id="2" manager="0"/&gt;
  &lt;person id="3" manager="2"/&gt;
  &lt;person id="4" manager="2"/&gt;
  &lt;person id="5" manager="1"/&gt;
  &lt;person id="6" manager="3"/&gt;
  &lt;person id="7" manager="6"/&gt;
  &lt;person id="8" manager="6"/&gt;
&lt;/doc&gt; }
         </eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $direct-reports := fn($p as element(person)) as element(person)* {
  $p/../person[@manager = $p/@id]
}
         </eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">transitive-closure(
  $data//person[@id = "2"],
  $direct-reports
)/string(@id)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"3", "4", "6", "7", "8"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">transitive-closure(
  $data, 
  function { child::* }
)/@id ! string()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"0", "1", "2", "3", "4", "5", "6", "7", "8"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>The following example, given <code nobreak="false">$root</code> as the root of an XSLT stylesheet module, returns the URIs
            of all stylesheet modules reachable using <code nobreak="false">xsl:import</code> and <code nobreak="false">xsl:include</code> declarations:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">transitive-closure($root, fn { document(//(xsl:import|xsl:include)/@href) }) 
=!&gt; document-uri()</eg></td></tr><tr><td colspan="2" rowspan="1"><p>This example uses the XSLT-defined <code nobreak="false">document()</code> function.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-while-do"><head>fn:while-do</head><changes><change issue="946" PR="962" date="2024-01-23">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Processes a supplied value repeatedly, continuing while some condition remains true,
            and returning the first value that does not satisfy the condition.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="while-do" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="predicate" type="fn(item()*, xs:integer) as xs:boolean?"/><arg name="action" type="fn(item()*, xs:integer) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function behaves as follows:</p><olist><item><p><code nobreak="false">$pos</code> is initially set to <code nobreak="false">1</code>.</p></item><item><p><code nobreak="false">$predicate($input, $pos)</code> is evaluated. If the result is
                  <code nobreak="false">false</code> or <code nobreak="false">()</code>, the function returns the value of <code nobreak="false">$input</code>.</p></item><item><p>Otherwise, <code nobreak="false">$action($input, $pos)</code> is evaluated, the resulting value is
                  used as a new <code nobreak="false">$input</code>, and the process repeats from step 2 with
                  <code nobreak="false">$pos</code> incremented by <code nobreak="false">1</code>.</p></item></olist></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function delivers the same result as the following XQuery implementation.</p><eg xml:space="preserve">declare %private function while-do-helper(
  $input     as item()*,
  $predicate as fn(item()*, xs:integer) as xs:boolean?,
  $action    as fn(item()*, xs:integer) as item()*,
  $pos       as xs:integer
) as item()* {
  if ($predicate($input, $pos))
  then while-do-helper($action($input, $pos), $predicate, $action, $pos + 1)
  else $input
};

declare function while-do(
  $input     as item()*,
  $predicate as fn(item()*, xs:integer) as xs:boolean?,
  $action    as fn(item()*, xs:integer) as item()*
) as item()* {
  while-do-helper($input, $predicate, $action, 1)
};</eg></def></gitem><gitem><label>Notes</label><def><note><p>While-do loops are very common in procedural programming languages, and this function
            provides a way to write functionally clean and interruptible iterations without
            side-effects. As long as a given condition is met, an new value is computed and tested
            again. Depending on the use case, the value can be a simple atomic item or an arbitrarily
            complex data structure.</p><p>The function <function>fn:do-until</function> can be used to perform the action before the
            first predicate test.</p><p>Note that, just as when writing recursive functions, it is easy to construct infinite
            loops.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">while-do(2, fn { . &lt;= 100 }, fn { . * . })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">256</eg><p><emph>(The loop is interrupted as soon as the computed product is greater
                  than 100.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
while-do(
  1,
  fn($num, $pos) { $pos &lt;= 10 },
  fn($num, $pos) { $num * $pos }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">3628800</eg><p><emph>(This returns the factorial of 10, i.e., the product of all integers from 1 to 10.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $input := (0 to 4, 6 to 10)
return while-do(
  0,
  fn($n) { $n = $input },
  fn($n) { $n + 1 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">5</eg><p><emph>(This returns the first positive number missing in a sequence.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
while-do(
  1 to 9,
  fn($value) { head($value) &lt; 5 },
  fn($value) { tail($value) }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">5, 6, 7, 8, 9</eg><p><emph>(The first number of a sequence is removed as long as it is smaller than 5.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $input := 3936256
return while-do(
  $input,
  fn($result) { abs($result * $result - $input) &gt;= 0.0000000001 },
  fn($guess) { ($guess + $input div $guess) div 2 }
) =&gt; round(5)
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1984</eg><p><emph>(This computes the square root of a number.)</emph></p></td></tr><tr><td colspan="2" rowspan="1"><p>The following example generates random doubles. It is interrupted once a number
               exceeds a given limit:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">
let $result := while-do(
  random-number-generator(),
  fn($random) {
    $random?number &lt; 0.8
  },
  fn($random) {
    map:put($random?next(), 'numbers', ($random?numbers, $random?number))
  }
)
return $result?numbers
</eg></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="boolean-functions"><head>Processing booleans</head><p>This section defines functions and operators on the <code nobreak="false">xs:boolean</code> datatype.</p><div2 id="boolean-constructors"><head>Boolean constant functions</head><p>Since no literals are defined in XPath to reference the constant boolean values <code nobreak="false">true</code> and <code nobreak="false">false</code>,
			two functions are provided for the purpose.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:true</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:boolean</code> value <code nobreak="false">true</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:false</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:boolean</code> value <code nobreak="false">false</code>.</td></tr></tbody></table><div3 id="func-true"><head>fn:true</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:boolean</code> value <code nobreak="false">true</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="true" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The result is equivalent to <code nobreak="false">xs:boolean("1")</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">true()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:boolean(1)</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-false"><head>fn:false</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:boolean</code> value <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="false" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The result is equivalent to <code nobreak="false">xs:boolean("0")</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">false()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:boolean(0)</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="boolean-value-functions"><head>Functions on Boolean values</head><p>The following functions are defined on boolean values:</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:boolean</code></td><td rowspan="1" colspan="1">Computes the effective boolean value of the sequence <code nobreak="false">$input</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:not</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the effective boolean value of <code nobreak="false">$input</code> is
               <code nobreak="false">false</code>, or <code nobreak="false">false</code> if it is <code nobreak="false">true</code>.</td></tr></tbody></table><div3 id="func-boolean"><head>fn:boolean</head><glist><gitem><label>Summary</label><def><p>Computes the effective boolean value of the sequence <code nobreak="false">$input</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="boolean" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function computes the effective boolean value of a sequence, defined according to
            the following rules. See also <xspecref spec="XP40" ref="id-ebv"/>.</p><ulist><item><p>If <code nobreak="false">$input</code> is the empty sequence, <function>fn:boolean</function> returns
                     <code nobreak="false">false</code>.</p></item><item><p>If <code nobreak="false">$input</code> is a sequence whose first item is a <xtermref spec="DM40" ref="dt-GNode"/>
                  (a generalized node), <function>fn:boolean</function> returns <code nobreak="false">true</code>.</p></item><item><p>If <code nobreak="false">$input</code> is a singleton value of type <code nobreak="false">xs:boolean</code> or of a type 
                  derived from <code nobreak="false">xs:boolean</code>, <function>fn:boolean</function> returns
                     <code nobreak="false">$input</code>.</p></item><item><p>If <code nobreak="false">$input</code> is a singleton value of type <code nobreak="false">xs:untypedAtomic</code>, 
                  <code nobreak="false">xs:string</code>, <code nobreak="false">xs:anyURI</code>, or a type derived from <code nobreak="false">xs:string</code>
                  or <code nobreak="false">xs:anyURI</code>, <function>fn:boolean</function> returns <code nobreak="false">false</code> if the operand value has
                  zero length; otherwise it returns <code nobreak="false">true</code>.</p></item><item><p>If <code nobreak="false">$input</code> is a singleton value of any numeric type or a type derived
                  from a numeric type, <function>fn:boolean</function> returns <code nobreak="false">false</code> if the
                  operand value is <code nobreak="false">NaN</code> or is numerically equal to zero; otherwise it
                  returns <code nobreak="false">true</code>.</p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>In all cases other than those listed above, <function>fn:boolean</function> raises a type error <errorref class="RG" code="0006"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The result of this function is not necessarily the same as <code nobreak="false">$input cast as
               xs:boolean</code>. For example, <code nobreak="false">fn:boolean("false")</code> returns the value
               <code nobreak="false">true</code> whereas <code nobreak="false">"false" cast as xs:boolean</code> (which can also be
            written <code nobreak="false">xs:boolean("false")</code>) returns <code nobreak="false">false</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $abc := ("a", "b", "")</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">boolean($abc[1])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">boolean($abc[0])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">boolean($abc[3])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">fn:boolean($abc)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FORG0006.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">fn:boolean([])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FORG0006.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-not"><head>fn:not</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the effective boolean value of <code nobreak="false">$input</code> is
               <code nobreak="false">false</code>, or <code nobreak="false">false</code> if it is <code nobreak="false">true</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="not" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The value of <code nobreak="false">$input</code> is first reduced to an effective boolean value by
            applying the <code nobreak="false">fn:boolean()</code> function. The function returns <code nobreak="false">true</code>
            if the effective boolean value is <code nobreak="false">false</code>, or <code nobreak="false">false</code> if the
            effective boolean value is <code nobreak="false">true</code>. </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">not(true())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">not(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">not("false")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">fn:not(1 to 10)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FORG0006.</p></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="numeric-functions"><head>Processing numerics</head><changes><change issue="2520">Some operations must now be carried out following
            XSD 1.1 rules, where previously use of XSD 1.0 was permitted.</change></changes><p>This section specifies arithmetic operators on the numeric datatypes defined in
                    <bibref ref="xmlschema11-2"/>.</p><div2 id="numeric-types"><head>Numeric types</head><p>The operators described in this section are defined on the following atomic
                    types.</p><p role="type-hierarchy-figure">
<ulist role="type-hierarchy type-colors"><item role="primitive special root"><ulist><item role="primitive"><p role="item">
               <phrase>decimal</phrase>
            </p><ulist><item role="built-in-atomic"><p role="first">
                     <phrase>integer</phrase>
                  </p></item></ulist></item><item role="primitive"><p role="item">
               <phrase>double</phrase>
            </p></item><item role="primitive"><p role="item">
               <phrase>float</phrase>
            </p></item></ulist></item></ulist>

<ulist role="type-hierarchy type-colors"><item><p role="root"><phrase>Supertype</phrase></p><ulist><item><p><phrase>subtype</phrase></p></item></ulist></item></ulist>
<ulist role="type-legend type-colors"><item role="built-in-atomic"><p><phrase>Built-in atomic types</phrase></p></item></ulist>
</p><p>They also apply to types derived by restriction from the above types. </p><p>The type <code nobreak="false">xs:numeric</code> is defined as a union type whose member types are
            (in order) <code nobreak="false">xs:double</code>, <code nobreak="false">xs:float</code>, and <code nobreak="false">xs:decimal</code>. This type is implicitly imported
            into the static context, so it can also be used in defining the signature of user-written functions. Apart from the fact that
            it is implicitly imported, it behaves exactly like a user-defined type with the same definition. This means, for example:</p><ulist><item><p>If the expected type of a function parameter is given as <code nobreak="false">xs:numeric</code>, the actual value supplied
               can be an instance of any of these three types, or any type derived from these three by restriction (this includes the built-in
               type <code nobreak="false">xs:integer</code>, which is derived from <code nobreak="false">xs:decimal</code>).</p></item><item><p>If the expected type of a function parameter is given as <code nobreak="false">xs:numeric</code>, and the actual value supplied
                  is <code nobreak="false">xs:untypedAtomic</code> (or a node whose atomized value is <code nobreak="false">xs:untypedAtomic</code>), then it will
                  be cast to the union type <code nobreak="false">xs:numeric</code> using the rules in <specref ref="casting-to-union"/>.
               Because the lexical space of <code nobreak="false">xs:double</code> subsumes the lexical space of the other member types, and
               <code nobreak="false">xs:double</code> is listed first, the effect is that if the untyped atomic item is in the lexical space of
               <code nobreak="false">xs:double</code>, it will be converted to an <code nobreak="false">xs:double</code>, and if not, a dynamic error occurs.</p></item><item><p>When the return type of a function is given as <code nobreak="false">xs:numeric</code>, the actual value returned will be
               an instance of one of the three member types (and perhaps also of types derived from these by restriction). The rules
               for the particular function will specify how the type of the result depends on the values supplied as arguments.
               In many cases, for the functions in this specification, the result is defined to be the same type as the first
               argument.</p></item></ulist><note><p>
This specification uses  <bibref ref="ieee754-2019"/> arithmetic for <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> values.
One consequence of this is that some operations result in the value <code nobreak="false">NaN</code> (not a number), which
has the unusual property that it is not equal to itself. Another consequence is that some operations return the value negative zero.
This differs from <bibref ref="xmlschema-2"/>, which defines
<code nobreak="false">NaN</code> as being equal to itself and defines only a single zero in the value space.
 The text accompanying several functions defines behavior for both positive and negative zero inputs and outputs 
 in the interest of alignment with <bibref ref="ieee754-2019"/>. A conformant implementation must
 respect these semantics. In consequence, the expression <code nobreak="false">-0.0e0</code> (which is actually a unary minus operator 
    applied to an <code nobreak="false">xs:double</code> value) will always return negative zero: see <specref ref="func-numeric-unary-minus"/>. 
    As a concession to implementations that rely on implementations of XSD 1.0, 
 the lexical form <code nobreak="false">-0</code> <rfc2119>may</rfc2119> be converted to positive zero when validating
                  a node against the type <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code>,
                  but casting from <code nobreak="false">xs:string</code>
                  to <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> will always produce negative zero.
</p><p>XML Schema 1.1 introduces support for positive and negative zero as distinct values, and also uses the <bibref ref="ieee754-2019"/>
               semantics for comparisons involving <code nobreak="false">NaN</code>.</p></note></div2><div2 id="op.numeric"><head>Arithmetic operators on numeric values</head><p>The following functions define the semantics of arithmetic operators defined in 
			<bibref ref="xquery-40"/> and <bibref ref="xpath-40"/> on these numeric types. </p><table role="no-code-break data"><thead><tr><th rowspan="1" colspan="1">Operator</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:numeric-add</code>
                            </td><td rowspan="1" colspan="1">Addition</td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:numeric-subtract</code>
                            </td><td rowspan="1" colspan="1">Subtraction</td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:numeric-multiply</code>
                            </td><td rowspan="1" colspan="1">Multiplication</td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:numeric-divide</code>
                            </td><td rowspan="1" colspan="1">Division</td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:numeric-integer-divide</code>
                            </td><td rowspan="1" colspan="1">Integer division</td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:numeric-mod</code>
                            </td><td rowspan="1" colspan="1">Modulus</td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:numeric-unary-plus</code>
                            </td><td rowspan="1" colspan="1">Unary plus</td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:numeric-unary-minus</code>
                            </td><td rowspan="1" colspan="1">Unary minus (negation)</td></tr></tbody></table><p>The parameters and return types for the above operators are in most cases declared to be of type
               <code nobreak="false">xs:numeric</code>, which permits the basic numeric
                    types: <code nobreak="false">xs:integer</code>, <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:float</code>
                    and <code nobreak="false">xs:double</code>, and types derived from them.
               In general the two-argument functions require that both arguments are of the same primitive type,
            and they return a value of this same type.
               The exceptions are <code nobreak="false">op:numeric-divide</code>, which returns
                    an <code nobreak="false">xs:decimal</code> if called with two <code nobreak="false">xs:integer</code> operands,
                    and <code nobreak="false">op:numeric-integer-divide</code> which always returns an <code nobreak="false">xs:integer</code>.</p><p>If the two operands of an arithmetic expression are not of the same type, they
               may be converted to a common type as described in <xspecref spec="XP40" ref="id-arithmetic"/>. </p><p>The result type of operations depends on their argument datatypes and is defined
                    in the following table:</p><table role="no-code-break data"><thead><tr><th rowspan="1" colspan="1">Operator</th><th rowspan="1" colspan="1">Returns</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:operation(xs:integer, xs:integer)</code>
                            </td><td rowspan="1" colspan="1">
                                <code nobreak="false">xs:integer</code> (except for <code nobreak="false">op:numeric-divide(integer,
                                integer)</code>, which returns <code nobreak="false">xs:decimal</code>)</td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:operation(xs:decimal, xs:decimal)</code>
                            </td><td rowspan="1" colspan="1">
                                <code nobreak="false">xs:decimal</code>
                            </td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:operation(xs:float, xs:float)</code>
                            </td><td rowspan="1" colspan="1">
                                <code nobreak="false">xs:float</code>
                            </td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:operation(xs:double, xs:double)</code>
                            </td><td rowspan="1" colspan="1">
                                <code nobreak="false">xs:double</code>
                            </td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:operation(xs:integer)</code>
                            </td><td rowspan="1" colspan="1">
                                <code nobreak="false">xs:integer</code>
                            </td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:operation(xs:decimal)</code>
                            </td><td rowspan="1" colspan="1">
                                <code nobreak="false">xs:decimal</code>
                            </td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:operation(xs:float)</code>
                            </td><td rowspan="1" colspan="1">
                                <code nobreak="false">xs:float</code>
                            </td></tr><tr><td rowspan="1" colspan="1">
                                <code nobreak="false">op:operation(xs:double)</code>
                            </td><td rowspan="1" colspan="1">
                                <code nobreak="false">xs:double</code>
                            </td></tr></tbody></table><p>The basic rules for addition, subtraction, and multiplication
			of ordinary numbers are not set out in this specification; they are taken as given. In the case of <code nobreak="false">xs:double</code>
			and <code nobreak="false">xs:float</code> the rules are as defined in <bibref ref="ieee754-2019"/>. The rules for handling
			division and modulus operations, as well as the rules for handling special values such as infinity and <code nobreak="false">NaN</code>,
			and exception conditions such as overflow and underflow, are described more explicitly since they are not necessarily obvious.</p><p>On overflow and underflow situations during arithmetic operations, conforming
                    implementations <rfc2119>must</rfc2119> behave as follows:</p><ulist><item><p>For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> operations, overflow
                            behavior <rfc2119>must</rfc2119> be conformant with <bibref ref="ieee754-2019"/>. This specification allows the following options:</p><ulist><item><p>Raising a dynamic error <errorref class="AR" code="0002"/> via an
                                    overflow trap.</p></item><item><p>Returning <code nobreak="false">INF</code> or <code nobreak="false">-INF</code>.</p></item><item><p>Returning the largest (positive or negative) non-infinite number.</p></item></ulist></item><item><p>For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> operations,
                            underflow behavior <rfc2119>must</rfc2119> be conformant with <bibref ref="ieee754-2019"/>. This specification allows the following options:</p><ulist><item><p>Raising a dynamic error <errorref class="AR" code="0002"/> via an
                                    underflow trap.</p></item><item><p>Returning <code nobreak="false">0.0E0</code> or <code nobreak="false">+/- 2**Emin</code> or a
                                    denormalized value; where <code nobreak="false">Emin</code> is the smallest
                                    possible <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> exponent.</p></item></ulist></item><item><p>For <code nobreak="false">xs:decimal</code> operations, overflow behavior <rfc2119>must</rfc2119> 
                     raise a dynamic error <errorref class="AR" code="0002"/>. On
                            underflow, <code nobreak="false">0.0</code> must be returned.</p></item><item><p>For <code nobreak="false">xs:integer</code> operations, implementations that support
                            limited-precision integer operations <rfc2119>must</rfc2119> select from
                            the following options:</p><ulist><item><p> They <rfc2119>may</rfc2119> choose to always raise a dynamic
                                        error <errorref class="AR" code="0002"/>.</p></item><item><p> They <rfc2119>may</rfc2119> provide an <termref def="implementation-defined"/> mechanism that allows users to
                                    choose between raising an error and returning a result that is
                                    modulo the largest representable integer value. See <bibref ref="ISO10967"/>.</p></item></ulist></item></ulist><p>The functions <code nobreak="false">op:numeric-add</code>, <code nobreak="false">op:numeric-subtract</code>,
                    <code nobreak="false">op:numeric-multiply</code>, <code nobreak="false">op:numeric-divide</code>,
                    <code nobreak="false">op:numeric-integer-divide</code> and <code nobreak="false">op:numeric-mod</code> are each
                    defined for pairs of numeric operands, each of which has the same
                    type:<code nobreak="false">xs:integer</code>, <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:float</code>, or
                    <code nobreak="false">xs:double</code>. The functions <code nobreak="false">op:numeric-unary-plus</code> and
                    <code nobreak="false">op:numeric-unary-minus</code> are defined for a single operand whose type
                    is one of those same numeric types.</p><p> For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> arguments, if either
                    argument is <code nobreak="false">NaN</code>, the result is <code nobreak="false">NaN</code>.</p><p>For <code nobreak="false">xs:decimal</code> values, let <var>N</var> be the number of digits
            of precision supported by the implementation, and let <var>M</var> (<code nobreak="false">M &lt;= N</code>) be the minimum limit on the number of digits
            required for conformance (18 digits for XSD 1.0, 16 digits for XSD 1.1). Then for addition, subtraction, and multiplication
               operations, the returned result <rfc2119>should</rfc2119> be accurate to <var>N</var> digits of precision, and for division and modulus operations,
               the returned result <rfc2119>should</rfc2119> be accurate to at least <var>M</var> digits of precision. 
               The actual precision is <termref def="implementation-defined"/>. If the number
                    of digits in the mathematical result exceeds the number of digits that the implementation
                    retains for that operation, the result is truncated or rounded in an <termref def="implementation-defined"/> manner.</p><note><p>This specification does not determine whether <code nobreak="false">xs:decimal</code> operations are fixed point or floating point.
            In an implementation using floating point it is possible for very simple operations to require more digits of precision than
            are available; for example, adding <code nobreak="false">1e100</code> to <code nobreak="false">1e-100</code> requires 200 digits of precision for an
               accurate representation of the result.</p></note><p>The <bibref ref="ieee754-2019"/> specification also describes handling of
            two exception conditions called <code nobreak="false">divideByZero</code> and <code nobreak="false">invalidOperation</code>. The 
            IEEE <code nobreak="false">divideByZero</code> exception is raised not only by a direct attempt to divide by zero, but also by
            operations such as <code nobreak="false">log(0)</code>. The IEEE <code nobreak="false">invalidOperation</code> exception is raised by
            attempts to call a function with an argument that is outside the function’s domain (for example,
            <code nobreak="false">sqrt(-1)</code> or <code nobreak="false">log(-1)</code>). 
               Although IEEE defines these as exceptions, it also defines “default non-stop exception handling” in 
                  which the operation returns a defined result, typically positive or negative infinity, or <code nobreak="false">NaN</code>. With this 
                  function library,
               these IEEE exceptions do not cause a dynamic error
            at the application level; rather they result in the relevant function or operator returning
            the defined non-error result. 
               The underlying IEEE exception <rfc2119>may</rfc2119> be notified to the application
            or to the user by some <termref def="implementation-defined">implementation-defined</termref>
               warning condition, but the observable effect on an application 
               using the functions and operators defined in this specification is simply to return
               the defined result (typically <code nobreak="false">-INF</code>, <code nobreak="false">+INF</code>, or <code nobreak="false">NaN</code>) with no error.</p><p>The <bibref ref="ieee754-2019"/> specification distinguishes two <code nobreak="false">NaN</code> values:
               a quiet <code nobreak="false">NaN</code> and a signaling <code nobreak="false">NaN</code>. These two values are not distinguishable in the XDM model:
               the value spaces of <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> each include only a single
               <code nobreak="false">NaN</code> value. This does not prevent the implementation distinguishing them internally,
               and triggering different <termref def="implementation-defined">implementation-defined</termref>
               warning conditions, but such distinctions do not affect the observable behavior of an application 
               using the functions and operators defined in this specification.</p><note><p>Although comparison of numeric values across heterogeneous types has changed
            to convert both values to <code nobreak="false">xs:decimal</code>, arithmetic operations continue
            to use <code nobreak="false">xs:double</code> as the common type.</p></note><div3 id="func-numeric-add"><head>op:numeric-add</head><glist><gitem><label>Summary</label><def><p>Returns the arithmetic sum of its operands: (<code nobreak="false">$arg1 + $arg2</code>).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">+</code> operator when
         applied to two numeric values</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="numeric-add" return-type="xs:numeric" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:numeric"/><arg name="arg2" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="op.numeric"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p> For <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> values, if one of the operands is a
            zero or a finite number and the other is <code nobreak="false">INF</code> or <code nobreak="false">-INF</code>,
               <code nobreak="false">INF</code> or <code nobreak="false">-INF</code> is returned. If both operands are
               <code nobreak="false">INF</code>, <code nobreak="false">INF</code> is returned. If both operands are
               <code nobreak="false">-INF</code>, <code nobreak="false">-INF</code> is returned. If one of the operands is
               <code nobreak="false">INF</code> and the other is <code nobreak="false">-INF</code>, <code nobreak="false">NaN</code> is
            returned.</p></note></def></gitem></glist></div3><div3 id="func-numeric-subtract"><head>op:numeric-subtract</head><glist><gitem><label>Summary</label><def><p>Returns the arithmetic difference of its operands: (<code nobreak="false">$arg1 - $arg2</code>).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">-</code> operator when
         applied to two numeric values. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="numeric-subtract" return-type="xs:numeric" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:numeric"/><arg name="arg2" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="op.numeric"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p> For <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> values, if one of the operands is a
            zero or a finite number and the other is <code nobreak="false">INF</code> or <code nobreak="false">-INF</code>, an
            infinity of the appropriate sign is returned. If both operands are <code nobreak="false">INF</code> or
               <code nobreak="false">-INF</code>, <code nobreak="false">NaN</code> is returned. If one of the operands is
               <code nobreak="false">INF</code> and the other is <code nobreak="false">-INF</code>, an infinity of the appropriate
            sign is returned.</p></note></def></gitem></glist></div3><div3 id="func-numeric-multiply"><head>op:numeric-multiply</head><glist><gitem><label>Summary</label><def><p>Returns the arithmetic product of its operands: (<code nobreak="false">$arg1 * $arg2</code>).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">*</code> operator when
         applied to two numeric values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="numeric-multiply" return-type="xs:numeric" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:numeric"/><arg name="arg2" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="op.numeric"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p> For <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> values, if one of the operands is a
            zero and the other is an infinity, <code nobreak="false">NaN</code> is returned. If one of the operands
            is a non-zero number and the other is an infinity, an infinity with the appropriate sign
            is returned.</p></note></def></gitem></glist></div3><div3 id="func-numeric-divide"><head>op:numeric-divide</head><glist><gitem><label>Summary</label><def><p>Returns the arithmetic quotient of its operands: (<code nobreak="false">$arg1 div $arg2</code>).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">div</code> operator when
         applied to two numeric values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="numeric-divide" return-type="xs:numeric" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:numeric"/><arg name="arg2" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="op.numeric"/>.</p><p>As a special case, if the types of both <code nobreak="false">$arg1</code> and <code nobreak="false">$arg2</code> are
               <code nobreak="false">xs:integer</code>, then the return type is <code nobreak="false">xs:decimal</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="AR" code="0001"/> for <code nobreak="false">xs:decimal</code>
            and <code nobreak="false">xs:integer</code> operands, if the divisor is (positive or negative) zero.</p></def></gitem><gitem><label>Notes</label><def><note><p>For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> operands, floating point division
            is performed as specified in <bibref ref="ieee754-2019"/>. A positive number divided by
            positive zero returns <code nobreak="false">INF</code>. A negative number divided by positive zero
            returns <code nobreak="false">-INF</code>. Division by negative zero returns <code nobreak="false">-INF</code> and
               <code nobreak="false">INF</code>, respectively. Positive or negative zero divided by positive or
            negative zero returns <code nobreak="false">NaN</code>. Also, <code nobreak="false">INF</code> or <code nobreak="false">-INF</code>
            divided by <code nobreak="false">INF</code> or <code nobreak="false">-INF</code> returns <code nobreak="false">NaN</code>.</p></note></def></gitem></glist></div3><div3 id="func-numeric-integer-divide"><head>op:numeric-integer-divide</head><glist><gitem><label>Summary</label><def><p>Performs an integer division.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">idiv</code> operator when
         applied to two numeric values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="numeric-integer-divide" return-type="xs:integer" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:numeric"/><arg name="arg2" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="op.numeric"/>.</p><p>If <code nobreak="false">$arg2</code> is <code nobreak="false">INF</code> or <code nobreak="false">-INF</code>, and <code nobreak="false">$arg1</code>
            is not <code nobreak="false">INF</code> or <code nobreak="false">-INF</code>, then the result is zero.</p><p>Otherwise, subject to limits of precision and overflow/underflow conditions, the result
            is the largest (furthest from zero) <code nobreak="false">xs:integer</code> value <code nobreak="false">$N</code> such
            that the following expression is <code nobreak="false">true</code>:</p><eg xml:space="preserve">abs($N * $arg2) le abs($arg1) and
compare($N * $arg2, 0) eq compare($arg1, 0).</eg><note><p>The second term in this condition ensures that the result has the correct sign.</p></note><p>The implementation may adopt a different algorithm provided that it is equivalent to
            this formulation in all cases where <termref def="implementation-dependent">implementation-dependent</termref> or <termref def="implementation-defined">implementation-defined</termref> behavior does not affect the outcome, for example,
            the implementation-defined precision of the result of <code nobreak="false">xs:decimal</code>
            division.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="AR" code="0001"/> if the divisor is (positive
            or negative) zero.</p><p>A dynamic error is raised <errorref class="AR" code="0002"/> if either operand is
               <code nobreak="false">NaN</code> or if <code nobreak="false">$arg1</code> is <code nobreak="false">INF</code> or
            <code nobreak="false">-INF</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Except in situations involving errors, loss of precision, or overflow/underflow, the
            result of <code nobreak="false">$a idiv $b</code> is the same as <code nobreak="false">($a div $b) cast as
               xs:integer</code>.</p><p>The semantics of this function are different from integer division as defined in
            programming languages such as Java and C++.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(10, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(3, -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(-3, 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(-3, -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(9.0, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(-3.5, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(3.0, 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(3.1E1, 6)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">5</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-integer-divide(3.1E1, 7)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">4</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-numeric-mod"><head>op:numeric-mod</head><glist><gitem><label>Summary</label><def><p>Returns the remainder resulting from dividing <code nobreak="false">$arg1</code>, the dividend, by
               <code nobreak="false">$arg2</code>, the divisor. </p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">mod</code> operator when
         applied to two numeric values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="numeric-mod" return-type="xs:numeric" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:numeric"/><arg name="arg2" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="op.numeric"/>.</p><p>The operation <code nobreak="false">a mod b</code> for operands that are <code nobreak="false">xs:integer</code> or
               <code nobreak="false">xs:decimal</code>, or types derived from them, produces a result such that
               <code nobreak="false">(a idiv b) * b + (a mod b)</code> is equal to <code nobreak="false">a</code> and the magnitude of
            the result is always less than the magnitude of <code nobreak="false">b</code>. This identity holds even
            in the special case that the dividend is the negative integer of largest possible
            magnitude for its type and the divisor is -1 (the remainder is 0). It follows from this
            rule that the sign of the result is the sign of the dividend.</p><p> For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> operands the following rules
            apply:</p><ulist><item><p>If either operand is <code nobreak="false">NaN</code>, the result is <code nobreak="false">NaN</code>.</p></item><item><p>If the dividend is positive or negative infinity, or the divisor is positive or
                  negative zero (0), or both, the result is <code nobreak="false">NaN</code>.</p></item><item><p>If the dividend is finite and the divisor is an infinity, the result equals the
                  dividend.</p></item><item><p>If the dividend is positive or negative zero and the divisor is finite, the result
                  is the same as the dividend.</p></item><item><p>In the remaining cases, where neither positive or negative infinity, nor positive
                  or negative zero, nor <code nobreak="false">NaN</code> is involved, the result obeys <code nobreak="false">(a idiv
                     b)*b+(a mod b)</code> = <code nobreak="false">a</code>.
                  
                  Division is truncating division, analogous to integer division, not <bibref ref="ieee754-2019"/> rounding division i.e. additional digits are truncated,
                  not rounded to the required precision.</p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="AR" code="0001"/> for <code nobreak="false">xs:integer</code>
            and <code nobreak="false">xs:decimal</code> operands, if <code nobreak="false">$arg2</code> is zero.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-mod(10, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-mod(6, -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-mod(4.5, 1.2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.9</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">op:numeric-mod(1.23E2, 0.6E1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3.0E0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-numeric-unary-plus"><head>op:numeric-unary-plus</head><glist><gitem><label>Summary</label><def><p>Returns its operand with the sign unchanged: (<code nobreak="false">+ $arg</code>).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the unary <code nobreak="false">+</code> operator
         applied to a numeric value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="numeric-unary-plus" return-type="xs:numeric" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="op.numeric"/>.</p><p>The returned value is equal to <code nobreak="false">$arg</code>, and is an instance of
               <code nobreak="false">xs:integer</code>, <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:double</code>, or
               <code nobreak="false">xs:float</code> depending on the type of <code nobreak="false">$arg</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Because coercion rules are applied in the normal way, the unary
               <code nobreak="false">+</code> operator can be used to force conversion of an untyped node to a
            number: the result of <code nobreak="false">+@price</code> is the same as <code nobreak="false">xs:double(@price)</code>
            if the type of <code nobreak="false">@price</code> is <code nobreak="false">xs:untypedAtomic</code>.</p></note></def></gitem></glist></div3><div3 id="func-numeric-unary-minus"><head>op:numeric-unary-minus</head><glist><gitem><label>Summary</label><def><p>Returns its operand with the sign reversed: <code nobreak="false">-$arg</code>.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the unary <code nobreak="false">-</code> operator when
         applied to a numeric value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="numeric-unary-minus" return-type="xs:numeric" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="op.numeric"/>.</p><p>The returned value is an instance of <code nobreak="false">xs:integer</code>, <code nobreak="false">xs:decimal</code>,
               <code nobreak="false">xs:double</code>, or <code nobreak="false">xs:float</code> depending on the type of
               <code nobreak="false">$arg</code>.</p><p>For <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:decimal</code> arguments, <code nobreak="false">0</code> and
               <code nobreak="false">0.0</code> return <code nobreak="false">0</code> and <code nobreak="false">0.0</code>, respectively. For
               <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> arguments, <code nobreak="false">NaN</code> returns
               <code nobreak="false">NaN</code>, <code nobreak="false">0.0E0</code> returns <code nobreak="false">-0.0E0</code> and vice versa.
               <code nobreak="false">INF</code> returns <code nobreak="false">-INF</code>. <code nobreak="false">-INF</code> returns
               <code nobreak="false">INF</code>.</p></def></gitem></glist></div3></div2><div2 id="comp.numeric" diff="chg" at="A"><head>Comparing numeric values</head><changes><change issue="473" PR="482">Deleted an inaccurate statement concerning the behavior of NaN.</change><change issue="986">Comparison of mixed numeric types (for example <code nobreak="false">xs:double</code>
               and <code nobreak="false">xs:decimal</code>) now generally converts both values to <code nobreak="false">xs:decimal</code>.</change></changes><p>Numeric values can be compared using the function <function>fn:compare</function>.</p><p diff="chg" at="A">This function underpins the six value comparison operators <code nobreak="false">eq</code>, <code nobreak="false">ne</code>, <code nobreak="false">lt</code>,
               <code nobreak="false">le</code>, <code nobreak="false">gt</code>, and <code nobreak="false">ge</code> and the six general comparison
               operators <code nobreak="false">=</code>, <code nobreak="false">!=</code>, <code nobreak="false">&lt;</code>, <code nobreak="false">&lt;=</code>,
               <code nobreak="false">&gt;</code>, and <code nobreak="false">&gt;=</code>, which are all defined in terms of 
               the <function>fn:compare</function> function.</p><note><p diff="add" at="2023-12-05">For a description of the different ways of comparing numeric
               values using the operators <code nobreak="false">=</code> and <code nobreak="false">eq</code> and functions
               such as <function>fn:deep-equal</function>, <function>fn:compare</function>,
               and <function>fn:atomic-equal</function>, 
               see <xspecref spec="XP40" ref="id-atomic-comparisons"/>.</p></note></div2><div2 id="numeric-value-functions"><head>Functions on numeric values</head><p>The following functions are defined on numeric types. Each function returns a
                    value of the same type as the type of its argument.</p><ulist><item><p>If the argument is the empty sequence, the empty sequence is returned.</p></item><item><p>For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> arguments, if the
                            argument is <code nobreak="false">NaN</code>, <code nobreak="false">NaN</code> is returned.</p></item><item><p>With the exception of <function>fn:abs</function>, functions with arguments of 
                     type <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> that are positive or
                            negative infinity return positive or negative infinity.</p></item></ulist><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:abs</code></td><td rowspan="1" colspan="1">Returns the absolute value of <code nobreak="false">$value</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:ceiling</code></td><td rowspan="1" colspan="1">Rounds <code nobreak="false">$value</code> upwards to a whole number.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:divide-decimals</code></td><td rowspan="1" colspan="1">Divides one <code nobreak="false">xs:decimal</code> by another to a defined precision, returning
            both the quotient and the remainder.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:floor</code></td><td rowspan="1" colspan="1">Rounds <code nobreak="false">$value</code> downwards to a whole number.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:is-NaN</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the argument is the <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> value <code nobreak="false">NaN</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:round</code></td><td rowspan="1" colspan="1">Rounds a value to a specified number of decimal places, with control over how the rounding
            takes place.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:round-half-to-even</code></td><td rowspan="1" colspan="1">Rounds a value to a specified number of decimal places, rounding to make the last digit
            even if two such values are equally near.</td></tr></tbody></table><note><p>The <function>fn:round</function> function has been extended with a third argument
               in version 4.0 of this specification; this means that the <function>fn:ceiling</function>,
               <function>fn:floor</function>, and <function>fn:round-half-to-even</function> functions are now
               technically redundant. They are retained, however, both for backwards compatibility
               and for convenience.</p></note><div3 id="func-abs"><head>fn:abs</head><glist><gitem><label>Summary</label><def><p>Returns the absolute value of <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="abs" return-type="xs:numeric?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:numeric?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="numeric-value-functions"/>.</p><p>If <code nobreak="false">$value</code> is negative the function returns <code nobreak="false">-$value</code>, otherwise it
            returns <code nobreak="false">$value</code>.</p><p>For the four types <code nobreak="false">xs:float</code>,
               <code nobreak="false">xs:double</code>, <code nobreak="false">xs:decimal</code> and <code nobreak="false">xs:integer</code>, it is
            guaranteed that if the type of <code nobreak="false">$value</code> is an instance of type <var>T</var> then
            the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
            also be an instance of a type derived from one of these four by restriction. For example, if
            <code nobreak="false">$value</code> is an instance of <code nobreak="false">xs:positiveInteger</code> then the value of
            <code nobreak="false">$value</code>
            <rfc2119>may</rfc2119> be returned unchanged.</p><p>For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> arguments, if the argument is
            positive zero or negative zero, then positive zero is returned. If the argument is
            positive or negative infinity, positive infinity is returned.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">abs(10.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">10.5</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">abs(-10.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">10.5</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">abs(-math:log(0))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-ceiling"><head>fn:ceiling</head><glist><gitem><label>Summary</label><def><p>Rounds <code nobreak="false">$value</code> upwards to a whole number.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="ceiling" return-type="xs:numeric?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:numeric?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="numeric-value-functions"/>.</p><p>The function returns the smallest (closest to negative infinity) number with no
            fractional part that is not less than <code nobreak="false">$value</code>.</p><p>For the four types <code nobreak="false">xs:float</code>,
            <code nobreak="false">xs:double</code>, <code nobreak="false">xs:decimal</code> and <code nobreak="false">xs:integer</code>, it is
            guaranteed that if the type of <code nobreak="false">$value</code> is an instance of type <var>T</var> then
            the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
            also be an instance of a type derived from one of these four by restriction. For example, if
         <code nobreak="false">$value</code> is an instance of <code nobreak="false">xs:decimal</code> then the result <rfc2119>may</rfc2119>
         be an instance of <code nobreak="false">xs:integer</code>.</p><p>For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> arguments, if the argument is
            positive zero, then positive zero is returned. If the argument is negative zero, then
            negative zero is returned. If the argument is less than zero and greater than -1,
            negative zero is returned. If the argument is positive or negative infinity, 
            the value of the argument is returned.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">ceiling(10.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">11</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">ceiling(-10.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-10</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">ceiling(math:log(0))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-xs:double('INF')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-divide-decimals"><head>fn:divide-decimals</head><changes><change issue="1261" PR="1671" date="2025-01-01">New in 4.0.</change></changes><glist><gitem><label>Summary</label><def><p>Divides one <code nobreak="false">xs:decimal</code> by another to a defined precision, returning
            both the quotient and the remainder.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="divide-decimals" return-type="record(quotient as xs:decimal, remainder as xs:decimal)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:decimal"/><arg name="divisor" type="xs:decimal"/><arg name="precision" type="xs:integer?" default="0" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a record with two fields:</p><olist><item><p><code nobreak="false">quotient</code> is the <code nobreak="false">xs:decimal</code> value 
                  furthest from zero such that:</p><olist><item><p><code nobreak="false">quotient</code> is an exact multiple of ten to the power
                  of minus <code nobreak="false">$precision</code>;</p></item><item><p>the absolute value of <code nobreak="false">quotient</code> 
                     multipled by <code nobreak="false">$divisor</code> is less than or equal to the absolute
                  value of <code nobreak="false">$value</code>;</p></item><item><p>the sign of <code nobreak="false">quotient</code> is the same as the sign
                     of <code nobreak="false">op:numeric-divide($value, $divisor)</code>.</p></item></olist></item><item><p><code nobreak="false">remainder</code> is the exact result of subtracting <code nobreak="false">quotient</code>
               multiplied by <code nobreak="false">$divisor</code> from <code nobreak="false">$value</code>.</p></item></olist><p>There may be <termref def="implementation-defined"/> limits on the precision
         available. If the requested <code nobreak="false">$precision</code> is outside this range, it should
         be adjusted to the nearest value supported by the implementation.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="AR" code="0001"/> 
            if <code nobreak="false">$divisor</code> is zero.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">divide-decimals(120.6, 60.3, 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "quotient": 2, "remainder": 0 }</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">divide-decimals(10, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "quotient": 3, "remainder": 1 }</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">divide-decimals(10, -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "quotient": -3, "remainder": 1 }</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">divide-decimals(-10, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "quotient": -3, "remainder": -1 }</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">divide-decimals(-10, -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "quotient": 3, "remainder": -1 }</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">divide-decimals(10, 3, 6)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "quotient": 3.333333, "remainder": 0.000001 }</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">divide-decimals(100, 30)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "quotient": 3, "remainder": 10 }</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">divide-decimals(150_862, 7, -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "quotient": 21_000, "remainder": 3_862 }</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-floor"><head>fn:floor</head><glist><gitem><label>Summary</label><def><p>Rounds <code nobreak="false">$value</code> downwards to a whole number.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="floor" return-type="xs:numeric?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:numeric?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="numeric-value-functions"/>.</p><p>The function returns the largest (closest to positive infinity) number with no
            fractional part that is not greater than <code nobreak="false">$value</code>.</p><p>For the four types <code nobreak="false">xs:float</code>,
         <code nobreak="false">xs:double</code>, <code nobreak="false">xs:decimal</code> and <code nobreak="false">xs:integer</code>, it is
         guaranteed that if the type of <code nobreak="false">$value</code> is an instance of type <var>T</var> then
         the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
         also be an instance of a type derived from one of these four by restriction. For example, if
         <code nobreak="false">$value</code> is an instance of <code nobreak="false">xs:decimal</code> then the result <rfc2119>may</rfc2119>
         be an instance of <code nobreak="false">xs:integer</code>.</p><p>For <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> arguments, if the argument is
            positive zero, then positive zero is returned. If the argument is negative zero, then
            negative zero is returned. If the argument is positive or negative infinity, 
            the value of the argument is returned.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">floor(10.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">10</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">floor(-10.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-11</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(0) =&gt; floor()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-xs:double('INF')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-is-NaN" diff="add" at="A"><head>fn:is-NaN</head><changes><change date="2022-09-20">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the argument is the <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> value <code nobreak="false">NaN</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="is-NaN" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:anyAtomicType"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns <code nobreak="false">true</code> if <code nobreak="false">$value</code> is the <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> value <code nobreak="false">NaN</code>;
            otherwise it returns <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">is-NaN(23)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">is-NaN("NaN")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">is-NaN(number("twenty-three"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">is-NaN(math:sqrt(-1))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-round"><head>fn:round</head><changes><change issue="1187 1274" PR="1260 1275" date="2024-06-11">A third argument has been added, providing control over the rounding mode.</change><change issue="1705" PR="1711" date="2025-01-01">It is explicitly stated that the limits for <code nobreak="false">$precision</code>
            are implementation-defined.</change></changes><glist><gitem><label>Summary</label><def><p>Rounds a value to a specified number of decimal places, with control over how the rounding
            takes place.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="round" return-type="xs:numeric?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:numeric?"/><arg name="precision" type="xs:integer?" default="0" note="default-on-empty"/><arg name="mode" type="enum('floor',&#xA; 'ceiling',&#xA;                 'toward-zero',&#xA; 'away-from-zero',&#xA; 'half-to-floor',&#xA;                 'half-to-ceiling',&#xA; 'half-toward-zero',&#xA; 'half-away-from-zero',&#xA; 'half-to-even')?" default="'half-to-ceiling'" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="numeric-value-functions"/>.</p><p>The function returns a value that is close to <code nobreak="false">$value</code>
               and that is a multiple of ten to the power of minus
               <code nobreak="false">$precision</code>. The default value of <code nobreak="false">$precision</code>
            is zero, in which case the function returns a whole number (but not necessarily
            an <code nobreak="false">xs:integer</code>).</p><p>The detailed way in which rounding is performed depends on the value of
            <code nobreak="false">$mode</code>, as follows. Here <var>L</var>
         means the highest multiple of ten to the power
         of minus <code nobreak="false">$precision</code> that is less than or equal to <code nobreak="false">$value</code>,
         <var>U</var> means the lowest multiple of ten to the power
         of minus <code nobreak="false">$precision</code> that is greater than or equal to <code nobreak="false">$value</code>,
         <var>N</var> means the multiple of ten to the power
         of minus <code nobreak="false">$precision</code> that is numerically closest to <code nobreak="false">$value</code>,
         and <term>midway</term> means that <code nobreak="false">$value</code> is equal to the arithmetic
         mean of <var>L</var> and <var>U</var>.</p><table role="no-code-break data"><caption>Rounding Modes</caption><thead><tr><th rowspan="1" colspan="1">Rounding Mode</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'floor'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>L</var>.</p></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'ceiling'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>U</var>.</p></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'toward-zero'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>L</var> if <code nobreak="false">$value</code> is positive, otherwise <var>U</var>.</p></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'away-from-zero'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>U</var> if <code nobreak="false">$value</code> is positive, otherwise <var>L</var></p></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'half-to-floor'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>N</var>, unless midway, in which case <var>L</var>.</p></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'half-to-ceiling'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>N</var>, unless midway, in which case <var>U</var>. This is the default.</p></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'half-toward-zero'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>N</var>, unless midway, in which case it
                  returns <var>L</var> if <code nobreak="false">$value</code> is positive, otherwise <var>U</var>.</p></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'half-away-from-zero'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>N</var>, unless midway, in which case it
                  returns <var>U</var> if <code nobreak="false">$value</code> is positive, otherwise <var>L</var>.</p></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">'half-to-even'</code></p></td><td rowspan="1" colspan="1"><p>Returns <var>N</var>, unless midway, in which case it
                  returns whichever of <var>L</var> and <var>U</var> has a last significant
                  digit that is even.</p></td></tr></tbody></table><p>For the four types <code nobreak="false">xs:float</code>,
            <code nobreak="false">xs:double</code>, <code nobreak="false">xs:decimal</code> and <code nobreak="false">xs:integer</code>, it is
            guaranteed that if the type of <code nobreak="false">$value</code> is an instance of type <var>T</var> then
            the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
            also be an instance of a type derived from one of these four by restriction. For example, if
            <code nobreak="false">$value</code> is an instance of <code nobreak="false">xs:decimal</code> and <code nobreak="false">$precision</code> is 
            less than one, then the result <rfc2119>may</rfc2119>
            be an instance of <code nobreak="false">xs:integer</code>.</p><p>If the second argument is omitted or is the empty sequence,
            the function produces the same result as when
            <code nobreak="false">$precision = 0</code> (that is, it rounds to a whole number).</p><p>When <code nobreak="false">$value</code> is of type <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code>:</p><olist><item><p>If <code nobreak="false">$value</code> is <code nobreak="false">NaN</code>, positive or negative zero, or positive or negative
                  infinity, then the result is the same as the argument.</p></item><item><p>For other values, the argument is cast to <code nobreak="false">xs:decimal</code> using an
                  implementation of <code nobreak="false">xs:decimal</code> that imposes no limits on the number of
                  digits that can be represented. The function is applied to this
                     <code nobreak="false">xs:decimal</code> value, and the resulting <code nobreak="false">xs:decimal</code> is
                  cast back to <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> as appropriate to
                  form the function result. If the resulting <code nobreak="false">xs:decimal</code> value is zero,
                  then positive or negative zero is returned according to the sign of
                     <code nobreak="false">$value</code>.</p></item></olist><p>There may be <termref def="implementation-defined"/> limits on the precision
         available. If the requested <code nobreak="false">$precision</code> is outside this range, it should
         be adjusted to the nearest value supported by the implementation.</p></def></gitem><gitem><label>Notes</label><def><note><p>This function is typically used with a non-zero <code nobreak="false">$precision</code> in financial
            applications where the argument is of type <code nobreak="false">xs:decimal</code>. For arguments of
            type <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code> the results may be
            counter-intuitive. For example, consider <code nobreak="false">round(35.425e0, 2)</code>. The result is
            not <code nobreak="false">35.43</code>, as might be expected, but <code nobreak="false">35.42</code>.
            This is because the <code nobreak="false">xs:double</code> written as <code nobreak="false">35.425e0</code>
            has an exact value equal to <code nobreak="false">35.42499999999...</code>, which is closer to
            <code nobreak="false">35.42</code> than to <code nobreak="false">35.43</code>.</p><p>The call <code nobreak="false">round($v, 0, "floor")</code> is equivalent to <code nobreak="false">floor($v)</code>.</p><p>The call <code nobreak="false">round($v, 0, "ceiling")</code> is equivalent to <code nobreak="false">ceiling($v)</code>.</p><p>The call <code nobreak="false">round($v, $p, "half-to-even")</code> is equivalent to <code nobreak="false">round-half-to-even($v, $p)</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(2.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3.0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(2.4999)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2.0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-2.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-2.0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.125, 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.13</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(8452, -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">8500</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(3.1415e0, 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3.14e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(0) =&gt; round()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.7, 0, "floor")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.7, 0, "floor")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-2</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.7, 0, "ceiling")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.7, 0, "ceiling")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.7, 0, "toward-zero")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.7, 0, "toward-zero")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.7, 0, "away-from-zero")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.7, 0, "away-from-zero")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-2</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.125, 2, "half-to-floor")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.12</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.125, 2, "half-to-floor")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.13</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.125, 2, "half-to-ceiling")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.13</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.125, 2, "half-to-ceiling")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.12</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.125, 2, "half-toward-zero")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.12</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.125, 2, "half-toward-zero")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.12</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.125, 2, "half-away-from-zero")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.13</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.125, 2, "half-away-from-zero")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.13</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(1.125, 2, "half-to-even")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.12</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round(-1.125, 2, "half-to-even")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.12</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-round-half-to-even"><head>fn:round-half-to-even</head><changes><change issue="1705" PR="1711" date="2025-01-01">It is explicitly stated that the limits for <code nobreak="false">$precision</code>
            are implementation-defined.</change></changes><glist><gitem><label>Summary</label><def><p>Rounds a value to a specified number of decimal places, rounding to make the last digit
            even if two such values are equally near.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="round-half-to-even" return-type="xs:numeric?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:numeric?"/><arg name="precision" type="xs:integer?" default="0" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>General rules: see <specref ref="numeric-value-functions"/>.</p><p>The function returns the nearest (that is, numerically closest) value to
               <code nobreak="false">$value</code> that is a multiple of ten to the power of minus
               <code nobreak="false">$precision</code>. If two such values are equally near (e.g. if the fractional
            part in <code nobreak="false">$value</code> is exactly .500...), the function returns the one whose least
            significant digit is even.</p><p>For the four types <code nobreak="false">xs:float</code>,
            <code nobreak="false">xs:double</code>, <code nobreak="false">xs:decimal</code> and <code nobreak="false">xs:integer</code>, it is
            guaranteed that if the type of <code nobreak="false">$value</code> is an instance of type <var>T</var> then
            the result will also be an instance of <var>T</var>. The result <rfc2119>may</rfc2119>
            also be an instance of a type derived from one of these four by restriction. For example, if
            <code nobreak="false">$value</code> is an instance of <code nobreak="false">xs:decimal</code> and <code nobreak="false">$precision</code>
            is less than one, then the result <rfc2119>may</rfc2119>
            be an instance of <code nobreak="false">xs:integer</code>.</p><p>For arguments of type <code nobreak="false">xs:float</code> and <code nobreak="false">xs:double</code>:</p><olist><item><p>If the argument is <code nobreak="false">NaN</code>, positive or negative zero, or positive or
                  negative infinity, then the result is the same as the argument.</p></item><item><p>In all other cases, the argument is cast to <code nobreak="false">xs:decimal</code> using an
                  implementation of <code nobreak="false">xs:decimal</code> that imposes no limits on the number of digits that
                  can be represented. The function is applied to this <code nobreak="false">xs:decimal</code> value,
                  and the resulting <code nobreak="false">xs:decimal</code> is cast back to <code nobreak="false">xs:float</code> or
                     <code nobreak="false">xs:double</code> as appropriate to form the function result. If the
                  resulting <code nobreak="false">xs:decimal</code> value is zero, then positive or negative zero is
                  returned according to the sign of the original argument.</p></item></olist><p>There may be <termref def="implementation-defined"/> limits on the precision
         available. If the requested <code nobreak="false">$precision</code> is outside this range, it should
         be adjusted to the nearest value supported by the implementation.</p></def></gitem><gitem><label>Notes</label><def><note><p>This function is typically used in financial applications where the argument is of type
               <code nobreak="false">xs:decimal</code>. For arguments of type <code nobreak="false">xs:float</code> and
               <code nobreak="false">xs:double</code> the results may be counter-intuitive. For example, consider
               <code nobreak="false">round-half-to-even(xs:float(150.015), 2)</code>.
               The result is not <code nobreak="false">150.02</code> as might be expected, but <code nobreak="false">150.01</code>.
               This is because the conversion of the
               <code nobreak="false">xs:float</code> value represented by the literal <code nobreak="false">150.015</code> to an
               <code nobreak="false">xs:decimal</code> produces the <code nobreak="false">xs:decimal</code>
               value <code nobreak="false">150.014999389...</code>, which is closer to
               <code nobreak="false">150.01</code> than to <code nobreak="false">150.02</code>.</p><p>From 4.0, the effect of this function can also be achieved by
         calling <function>fn:round</function> with the third argument set to <code nobreak="false">"half-to-even"</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round-half-to-even(0.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round-half-to-even(1.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2.0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round-half-to-even(2.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2.0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round-half-to-even(3.567812e+3, 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3567.81e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round-half-to-even(4.7564e-3, 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">round-half-to-even(35612.25, -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">35600</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(0) =&gt; round-half-to-even()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-xs:double('INF')</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="parsing-numbers"><head>Parsing numbers</head><p>It is possible to convert strings to values of type <code nobreak="false">xs:integer</code>,
            <code nobreak="false">xs:float</code>, <code nobreak="false">xs:decimal</code>, or <code nobreak="false">xs:double</code>
            using the constructor functions described in <specref ref="constructor-functions"/>
            or using <code nobreak="false">cast</code> expressions as described in <specref ref="casting"/>.</p><p>In addition the <function>fn:number</function> function is available to convert strings
            to values of type <code nobreak="false">xs:double</code>. It differs from the <code nobreak="false">xs:double</code>
            constructor function in that any value outside the lexical space of the <code nobreak="false">xs:double</code>
            datatype is converted to the <code nobreak="false">xs:double</code> value <code nobreak="false">NaN</code>.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:number</code></td><td rowspan="1" colspan="1">Returns the value indicated by <code nobreak="false">$value</code> or, if <code nobreak="false">$value</code> is not
            specified, the context value after atomization, converted to an <code nobreak="false">xs:double</code>.
         </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-integer</code></td><td rowspan="1" colspan="1">Converts a string to an integer, recognizing any radix in the range 2 to 36.</td></tr></tbody></table><div3 id="func-number"><head>fn:number</head><glist><gitem><label>Summary</label><def><p>Returns the value indicated by <code nobreak="false">$value</code> or, if <code nobreak="false">$value</code> is not
            specified, the context value after atomization, converted to an <code nobreak="false">xs:double</code>.
         </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="number" return-type="xs:double" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:anyAtomicType?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence or if <code nobreak="false">$value</code> cannot be converted
            to an <code nobreak="false">xs:double</code>, the <code nobreak="false">xs:double</code> value <code nobreak="false">NaN</code> is
            returned. </p><p>Otherwise, <code nobreak="false">$value</code> is converted to an <code nobreak="false">xs:double</code> following the
            rules of <specref ref="casting-to-double"/>. If the conversion to <code nobreak="false">xs:double</code>
            fails, the <code nobreak="false">xs:double</code> value <code nobreak="false">NaN</code> is returned.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/>
            if <code nobreak="false">$value</code> is omitted and the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p><p>As a consequence of the rules given above, a type error is raised 
           <xerrorref spec="XP" class="TY" code="0004" type="type"/> if the context value
            cannot be atomized, or if the result of atomizing the context value is a sequence
            containing more than one atomic item.</p><!-- bug 16745 --></def></gitem><gitem><label>Notes</label><def><note><p>The string <code nobreak="false">+INF</code> is permitted as a representation of positive infinity,
            whether or not XSD 1.1 is supported. Similarly, <code nobreak="false">-0</code> and <code nobreak="false">0</code>
            produce negative zero and positive zero respectively.</p><p>Generally <function>fn:number</function> returns <code nobreak="false">NaN</code> rather than raising a dynamic
            error if the argument cannot be converted to <code nobreak="false">xs:double</code>. However, a type
            error is raised in the usual way if the supplied argument cannot be atomized or if the
            result of atomization does not match the required argument type.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;e price="12.1" discount="NONE"/&gt;</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">number(12)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.2e1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">number('12')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.2e1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">number('INF')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">number('NaN')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">number('non-numeric')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">number($e/@price)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.21e1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">number($e/@discount)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">number($e/@misspelt)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">("10", "11", "12") ! number()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e1, 1.1e1, 1.2e1</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-parse-integer" diff="add" at="2023-04-07"><head>fn:parse-integer</head><changes><change issue="241" PR="434" date="2023-04-25">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Converts a string to an integer, recognizing any radix in the range 2 to 36.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-integer" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="radix" type="xs:integer?" default="10" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the result is the empty sequence.</p><p>The supplied <code nobreak="false">$radix</code> must be in the range 2 to 36 inclusive.</p><p>The string <code nobreak="false">$value</code> is preprocessed by stripping all whitespace characters (including internal whitespace)
         and underscore characters.</p><p>After this process, the supplied value
          must consist of an optional sign (<code nobreak="false">+</code> or <code nobreak="false">-</code>)
         followed by a sequence of one or more generalized digits drawn from the first <code nobreak="false">$radix</code> characters
         in the alphabet <code nobreak="false">0123456789abcdefghijklmnopqrstuvwxyz</code>; upper-case alphabetics
         <code nobreak="false">A-Z</code> may be used in place of their lower-case equivalents.</p><p>The value of a generalized digit corresponds to its position in this alphabet.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression, except in error cases.</p><eg xml:space="preserve">let $alphabet := characters("0123456789abcdefghijklmnopqrstuvwxyz")
let $preprocessed := translate(
  $value, 
  codepoints-to-string((9, 10, 13, 32, 95)), 
  ""
)
let $digits := translate($preprocessed, "+-", "")
let $abs := sum(
  for $char at $p in reverse(characters(lower-case($digits)))
  return (index-of($alphabet, $char) - 1) * xs:integer(math:pow($radix, $p - 1))
)
return if (starts-with($preprocessed, "-")) then -$abs else +$abs</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RG" code="0011"/>
            if <code nobreak="false">$radix</code> is not in the range 2 to 36.</p><p>A dynamic error is raised <errorref class="RG" code="0012"/>
            if, after stripping whitespace and underscores and the optional leading sign, 
            <code nobreak="false">$value</code> is a zero-length string,
            or if it contains a character
         that is not among the first <code nobreak="false">$radix</code> characters in the
            alphabet <code nobreak="false">0123456789abcdefghijklmnopqrstuvwxyz</code>, or the
         upper-case equivalent of such a character.</p><p>A dynamic error is raised <errorref class="CA" code="0003"/>
            if the value of the resulting integer exceeds the implementation-dependent
            limit on the size of an <code nobreak="false">xs:integer</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>When <code nobreak="false">$radix</code> takes its default value of <code nobreak="false">10</code>,
            the function delivers the same result as casting <code nobreak="false">$value</code> 
            (after removal of whitespace and underscores) to <code nobreak="false">xs:integer</code>.</p><p>If underscores or whitespace in the input need to be rejected, then
         the string should first be validated, perhaps using <function>fn:matches</function>.</p><p>If other characters may legitimately appear in the input, for example
         a leading <code nobreak="false">0x</code>, then this must first be removed by pre-processing the input.</p><p>If the input uses a different family of digits, then the value should first
         be converted to the required digits using <function>fn:translate</function>.</p><p>A string in the lexical space of <code nobreak="false">xs:hexBinary</code> will always
         be an acceptable input, provided it is not too long. So, for example, the expression
         <code nobreak="false">"1DE=" =&gt; xs:base64Binary() =&gt; xs:hexBinary() =&gt; xs:string() =&gt; parse-integer(16)</code>
         can be used to convert the Base 64 value <code nobreak="false">1DE=</code> to the integer 54321, via the 
         hexadecimal string <code nobreak="false">D431</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer(" 200 ")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">200</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer("-20")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-20</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer(" +100")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">100</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer("ff", 16)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">255</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer("FFFF FFFF", 16)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">4294967295</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer("-FFFF_FFFF", 16)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-4294967295</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer("377", 8)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">255</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer("101", 2)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">5</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-integer("vv", 32)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1023</code></p></td></tr><tr><td colspan="2" rowspan="1"><p>Alphabetic base-26 numbering systems (hexavigesimal) can be parsed via translation.
               Note, enumerating systems that do not assign a symbol to zero (e.g., spreadsheet
               columns) must be preprocessed in a different fashion.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">lower-case("AAB")
=&gt; translate("abcdefghijklmnopqrstuvwxyz", "0123456789abcdefghijklmnop")
=&gt; parse-integer(26)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Digit-based numeration systems comparable to the Arabic numbers 0 through 9 can be
               parsed via translation.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
translate(value := '٢٠٢٣', replace := '٠١٢٣٤٥٦٧٨٩', with := '0123456789')
=&gt; parse-integer()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2023</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="formatting-integers"><head>Formatting integers</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:format-integer</code></td><td rowspan="1" colspan="1">Formats an integer according to a given picture string, using the conventions of a given
            natural language if specified.</td></tr></tbody></table><div3 id="func-format-integer"><head>fn:format-integer</head><changes><change issue="241" PR="434" date="2023-04-07">The function has been extended to allow output in a radix other than 10, for example in hexadecimal.</change></changes><glist><gitem><label>Summary</label><def><p>Formats an integer according to a given picture string, using the conventions of a given
            natural language if specified.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="format-integer" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:integer?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		default language.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns a zero-length
            string.</p><p>In all other cases, the <code nobreak="false">$picture</code> argument describes the format in which
               <code nobreak="false">$value</code> is output.</p><p>The rules that follow describe how non-negative numbers are output. If the value of
               <code nobreak="false">$value</code> is negative, the rules below are applied to the absolute value of
               <code nobreak="false">$value</code>, and a minus sign is prepended to the result.</p><p>The value of <code nobreak="false">$picture</code> consists of the following, in order:</p><olist><item><p diff="add" at="2023-04-25">An optional radix, which is an integer in the range 2 to 36, written using ASCII
            digits (<code nobreak="false">0-9</code>) without any leading zero;</p></item><item><p diff="add" at="2023-04-25">A circumflex (<code nobreak="false">^</code>), which is present if the radix is present, and absent otherwise.</p><p diff="add" at="2023-04-25">A circumflex is recognized as marking the presence of a radix only
                  if (a) it is immediately preceded by an integer
                  in the range 2 to 36, and (b) it is
                  followed (somewhere within the primary format token) by an <code nobreak="false">"X"</code>
                  or <code nobreak="false">"x"</code>. In other cases, the circumflex is treated as a grouping separator.
                  For example, the picture <code nobreak="false">9^000</code> outputs the number
                  2345 as <code nobreak="false">"2^345"</code>, whereas <code nobreak="false">9^XXX</code> outputs <code nobreak="false">"3185"</code>.
                  This rule is to ensure backwards compatibility.</p></item><item><p>A primary format token. This is always present and
               <rfc2119>must not</rfc2119> be zero-length.</p></item><item><p>An optional format modifier.</p><p>If the string contains one or more
                  semicolons then the last semicolon is taken as terminating the primary
                  format token, and everything that follows is taken as the format modifier; if the string
                  contains no semicolon then 
                  the format modifier is taken to be absent (which is equivalent to supplying a
                  zero-length string).</p></item></olist><p diff="add" at="2023-04-07">If a radix is present, then the primary format token must follow the
            rules for a <var>digit-pattern</var>.</p><p>The primary format token is classified as one of the following:</p><olist><item><p>A <var>digit-pattern</var> made up of <var>optional-digit-signs</var>,
                     <var>mandatory-digit-signs</var>, and <var>grouping-separator-signs</var>.</p><ulist><item><p>The <var>optional-digit-sign</var> is the character <code nobreak="false">#</code>.</p></item><item><p><phrase diff="add" at="2023-04-07">If the radix is absent, then</phrase>
                        a <var>mandatory-digit-sign</var> is a <termref def="character">character</termref> in Unicode category <var>Nd</var>. All
                           <var>mandatory-digit-signs</var> within the format token
                           <rfc2119>must</rfc2119> be from the same digit family, where a digit
                        family is a sequence of ten consecutive characters in Unicode category <var>Nd</var>,
                        having digit values <code nobreak="false">0</code> through <code nobreak="false">9</code>.
                        Within the format token, these digits are
                        interchangeable: a three-digit number may thus be indicated equivalently by
                        <code nobreak="false">000</code>, <code nobreak="false">001</code>, or <code nobreak="false">999</code>.</p><p>If the primary format token contains at least one Unicode digit,
                        then the primary format token is taken
                        as a decimal digit pattern, and in this case it <rfc2119>must</rfc2119> match the
                        regular expression <code nobreak="false">^((\p{Nd}|#|[^\p{N}\p{L}])+?)$</code>. If it contains a
                        digit but does not match this pattern, a dynamic error is raised <errorref class="DF" code="1310"/>.</p></item><item><p><phrase diff="add" at="2023-04-07">If the radix (call it <var>R</var>) is 
                        present (including the case where an explicit radix of 10 is used), then</phrase>
                        the character used as the <var>mandatory-digit-sign</var> is either <code nobreak="false">"x"</code>
                        or <code nobreak="false">"X"</code>. If any <var>mandatory-digit-sign</var> is upper-case <code nobreak="false">"X"</code>, then all
                        <var>mandatory-digit-signs</var> must be upper-case <code nobreak="false">"X"</code>. The digit family
                        used in the output comprises the first <var>R</var> characters of the
                        alphabet <code nobreak="false">0123456789abcdefghijklmnopqrstuvwxyz</code>, but using upper-case 
                        letters in place of lower-case if an upper-case <code nobreak="false">"X"</code> is used
                        as the <var>mandatory-digit-sign</var>.</p><p diff="add" at="2023-04-25">In this case the primary format token <rfc2119>must</rfc2119> match the
                        regular expression <code nobreak="false">^(([Xx#]|[^\p{N}\p{L}])+?)$</code></p></item><item><p>a <var>grouping-separator-sign</var> is a non-alphanumeric character, that
                        is a <termref def="character">character</termref> whose Unicode category is
                        other than <var>Nd</var>, <var>Nl</var>, <var>No</var>, <var>Lu</var>, <var>Ll</var>, 
                        <var>Lt</var>, <var>Lm</var> or <var>Lo</var>.</p></item></ulist><note><p>If a semicolon is to be used as a grouping separator, then the primary format
                     token as a whole must be followed by another semicolon, to ensure that the
                     grouping separator is not mistaken as a separator between the primary format
                     token and the format modifier.</p></note><p>There <rfc2119>must</rfc2119> be at least one <var>mandatory-digit-sign</var>.
                  There may be zero or more <var>optional-digit-signs</var>, and (if present) these
                     <rfc2119>must</rfc2119> precede all <var>mandatory-digit-signs</var>. There may
                  be zero or more <var>grouping-separator-signs</var>. A
                     <var>grouping-separator-sign</var>
                  <rfc2119>must not</rfc2119> appear at the start or end of the
                     <var>digit-pattern</var>, nor adjacent to another
                     <var>grouping-separator-sign</var>.</p><p>The corresponding output is a number in the specified radix, using this digit family, with
                  at least as many digits as there are <var>mandatory-digit-signs</var> in the
                  format token. Thus:</p><ulist><item><p>A format token <code nobreak="false">1</code> generates the sequence <code nobreak="false">0 1
                        2 ... 10 11 12 ...</code></p></item><item><p>A format token <code nobreak="false">01</code> (or equivalently,
                        <code nobreak="false">00</code> or <code nobreak="false">99</code>) generates the sequence <code nobreak="false">00 01 02 ...
                           09 10 11 12 ... 99 100 101</code></p></item><item><p>A format token of <char>U+0661</char>
                         generates the sequence <code nobreak="false">١</code> then <code nobreak="false">٢</code>
                        then <code nobreak="false">٣</code> ...</p></item><item><p>A format token of <code nobreak="false">16^xx</code> generates the sequence <code nobreak="false">00 01 02 03
                     ... 08 09 0a 0b 0c 0d 0e 0f 10 11 ...</code></p></item><item><p>A format token of <code nobreak="false">16^X</code> generates the sequence <code nobreak="false">0 1 2 3
                        ... 8 9 A B C D E F 10 11 ...</code></p></item></ulist><p>The <var>grouping-separator-signs</var> are handled as follows:</p><olist><item><p>The position of
                        grouping separators within the format token, counting backwards from the last
                        digit, indicates the position of grouping separators to appear within the
                        formatted number, and the character used as the <var>grouping-separator-sign</var>
                        within the format token indicates the character to be used as the corresponding
                        grouping separator in the formatted number.
                     </p></item><item><p>More specifically, the <term>position</term> of a grouping separator is
                        the number of <var>optional-digit-signs</var> and <var>mandatory-digit-signs</var> appearing
                        between the grouping separator and the right-hand end of the primary format token.</p></item><item><p>Grouping separators are defined to be <term>regular</term> if the following conditions apply:</p><olist><item><p>There is at least one grouping separator.</p></item><item><p>Every grouping separator is the same character (call it <var>C</var>).</p></item><item><p>There is a positive integer <var>G</var> (the grouping size) such that:</p><olist><item><p>The position of every grouping separator is an integer multiple of <var>G</var>, and</p></item><item><p>Every positive integer multiple of <var>G</var> that is less than the number of 
                              <var>optional-digit-signs</var> and <var>mandatory-digit-signs</var> in the primary format token
                              is the position of a grouping separator.</p></item></olist></item></olist></item><item><p>The <term>grouping separator template</term> is a (possibly infinite) set of (position, character) pairs.</p></item><item><p>If grouping separators are regular, then the grouping separator template contains one pair of the form <code nobreak="false">(n×G, C)</code>
                     for every positive integer <var>n</var> where <var>G</var> is the grouping size and <var>C</var> is the grouping character.</p></item><item><p>Otherwise (when grouping separators are not regular), the grouping separator template contains one pair of the form
                     <code nobreak="false">(P, C)</code> for every grouping separator found in the primary formatting token, where <var>C</var> is the grouping
                     separator character and <var>P</var> is its position.</p></item><item><note><p>If there are no grouping separators, then the grouping separator template is the empty set.</p></note></item></olist><p>The number is formatted as follows:</p><olist><item><p>Let <var>S/1</var> be the result of formatting the supplied number 
                        <phrase diff="chg" at="2023-04-07">in the appropriate radix:
                        for radix 10 this will be the value obtained</phrase> by casting
                  it to <code nobreak="false">xs:string</code>.</p></item><item><p>Let <var>S/2</var> be the result of padding <var>S/1</var> on the left with as many leading zeroes
                  as are needed to ensure that it contains at least as many digits as the number of <var>mandatory-digit-signs</var>
                  in the primary format token.</p></item><item><p>Let <var>S/3</var> be the result of replacing all decimal digits (0-9) in <var>S/2</var> with the corresponding
                     digits from the selected digit family. <phrase diff="add" at="2023-04-27">(This has no effect when the selected digit family uses ASCII digits (0-9),
                     which will always be the case if a radix is specified.)</phrase></p></item><item><p>Let <var>S/4</var> be the result of inserting grouping separators into <var>S/3</var>: for every (position 
                     <var>P</var>, character <var>C</var>) pair in the grouping separator template where <var>P</var> is less than the number
                  of digits in <var>S/3</var>, insert character <var>C</var> into <var>S/3</var> at position <var>P</var>, counting from 
                  the right-hand end.</p></item><item><p>Let <var>S/5</var> be the result of converting <var>S/4</var> into ordinal form, if an ordinal modifier
                  is present, as described below.</p></item><item><p>The result of the function is then <var>S/5</var>.</p></item></olist></item><item><p>The format token <code nobreak="false">A</code>, which generates the sequence <code nobreak="false">A B C ... Z AA
                     AB AC...</code>.</p></item><item><p>The format token <code nobreak="false">a</code>, which generates the sequence <code nobreak="false">a b c ... z aa
                     ab ac...</code>.</p></item><item><p>The format token <code nobreak="false">i</code>, which generates the sequence <code nobreak="false">i ii iii iv v
                     vi vii viii ix x ...</code>.</p></item><item><p>The format token <code nobreak="false">I</code>, which generates the sequence <code nobreak="false">I II III IV V
                     VI VII VIII IX X ...</code>.</p></item><item><p>The format token <code nobreak="false">w</code>, which generates numbers written as lower-case
                  words, for example in English, <code nobreak="false">one two three four ...</code>
               </p></item><item><p>The format token <code nobreak="false">W</code>, which generates numbers written as upper-case
                  words, for example in English, <code nobreak="false">ONE TWO THREE FOUR ...</code>
               </p></item><item><p>The format token <code nobreak="false">Ww</code>, which generates numbers written as title-case
                  words, for example in English, <code nobreak="false">One Two Three Four ...</code>
               </p></item><item><p>Any other format token, which indicates a numbering sequence in which that token
                  represents the number 1 (one) (but see the note below).
                  
                  It is <termref def="implementation-defined">implementation-defined</termref> which
                  numbering sequences, additional to those listed above, are supported. If an
                  implementation does not support a numbering sequence represented by the given
                  token, it <rfc2119>must</rfc2119> use a format token of <code nobreak="false">1</code>.</p><note><p>In some traditional numbering sequences additional signs are added to denote
                     that the letters should be interpreted as numbers, for example, in ancient Greek
                      <char>U+0374</char> and sometimes <char>U+0375</char>. These should not be
                     included in the format token.
                  </p></note></item></olist><p>For all format tokens other than a <var>digit-pattern</var>, there 
            <rfc2119>may</rfc2119> be <termref def="implementation-defined">implementation-defined</termref> lower and upper bounds on the range of numbers that
            can be formatted using this format token; indeed, for some numbering sequences there may
            be intrinsic limits. For example, the format token <char>U+2460</char>  has a range imposed by the Unicode character repertoire — <phrase>zero to 20</phrase>
            in Unicode versions prior to <phrase>3.2</phrase>, or <phrase>zero to 50</phrase> in subsequent versions. For the numbering
            sequences described above any upper bound imposed by the implementation <rfc2119>must
               not</rfc2119> be less than 1000 (one thousand) and any lower bound must not be
            greater than 1. Numbers that fall outside this range <rfc2119>must</rfc2119> be
            formatted using the format token <code nobreak="false">1</code>.</p><p>The above expansions of numbering sequences for format tokens such as <code nobreak="false">a</code> and
               <code nobreak="false">i</code> are indicative but not prescriptive. There are various conventions in
            use for how alphabetic sequences continue when the alphabet is exhausted, and differing
            conventions for how roman numerals are written (for example, <code nobreak="false">IV</code> versus
               <code nobreak="false">IIII</code> as the representation of the number 4). Sometimes alphabetic
            sequences are used that omit letters such as <code nobreak="false">i</code> and <code nobreak="false">o</code>. This
            specification does not prescribe the detail of any sequence other than those sequences
            consisting entirely of decimal digits.</p><p>Many numbering sequences are language-sensitive. This applies especially to the sequence
            selected by the tokens <code nobreak="false">w</code>, <code nobreak="false">W</code>, and <code nobreak="false">Ww</code>. It also
            applies to other sequences, for example different languages using the Cyrillic alphabet
            use different sequences of characters, each starting with the letter <char>U+0410</char> . In such cases, the <code nobreak="false">$language</code> argument specifies which
            language conventions are to be used. If the argument is specified, the value
               <rfc2119>should</rfc2119> be either the empty sequence or a value that would be valid
            for the <code nobreak="false">xml:lang</code> attribute (see <bibref ref="xml"/>). Note that this
            permits the identification of sublanguages based on country codes (from ISO 3166-1) as
            well as identification of dialects and regions within a country.</p><p>The set of languages for which numbering is supported is <termref def="implementation-defined">implementation-defined</termref>. If the <code nobreak="false">$language</code> argument is absent, or is
            set to the empty sequence, or is invalid, or is not a language supported by the
            implementation, then the number is formatted using the default language from the dynamic
            context. </p><p>The format modifier <rfc2119>must</rfc2119> be a string that matches the regular
            expression <code nobreak="false">^([co](\(.+\))?)?[at]?$</code>. That is, if it is present it must
            consist of one or more of the following, in order:</p><ulist><item><p>either <code nobreak="false">c</code> or <code nobreak="false">o</code>, optionally followed by a sequence of
                  characters enclosed between parentheses, to indicate cardinal or ordinal numbering
                  respectively, the default being cardinal numbering</p></item><item><p>either <code nobreak="false">a</code> or <code nobreak="false">t</code>, to indicate alphabetic or traditional
                  numbering respectively, the default being <termref def="implementation-defined">implementation-defined</termref>.</p></item></ulist><p>If the <code nobreak="false">o</code> modifier is present, this indicates a request to output ordinal
            numbers rather than cardinal numbers. For example, in English, when used with the format
            token <code nobreak="false">1</code>, this outputs the sequence <code nobreak="false">1st 2nd 3rd 4th ...</code>, and
            when used with the format token <code nobreak="false">w</code> outputs the sequence <code nobreak="false">first second
               third fourth ...</code>.</p><p>The string of characters between the parentheses, if present, is used to select between
            other possible variations of cardinal or ordinal numbering sequences. The interpretation
            of this string is <termref def="implementation-defined">implementation-defined</termref>. No error occurs if the implementation does not
            define any interpretation for the defined string.</p><p>It is <termref def="implementation-defined">implementation-defined</termref> what
            combinations of values of the format token, the language, and the cardinal/ordinal
            modifier are supported. If ordinal numbering is not supported for the combination of the
            format token, the language, and the string appearing in parentheses, the request is
            ignored and cardinal numbers are generated instead.</p><p>The use of the <code nobreak="false">a</code> or <code nobreak="false">t</code> modifier disambiguates between numbering
            sequences that use letters. In many languages there are two commonly used numbering
            sequences that use letters. One numbering sequence assigns numeric values to letters in
            alphabetic sequence, and the other assigns numeric values to each letter in some other
            manner traditional in that language. In English, these would correspond to the numbering
            sequences specified by the format tokens <code nobreak="false">a</code> and <code nobreak="false">i</code>. In some
            languages, the first member of each sequence is the same, and so the format token alone
            would be ambiguous. In the absence of the <code nobreak="false">a</code> or <code nobreak="false">t</code> modifier, the
            default is <termref def="implementation-defined">implementation-defined</termref>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DF" code="1310"/> if the format token is
            invalid, that is, if it violates any mandatory rules (indicated by an emphasized
               <rfc2119>must</rfc2119> or <rfc2119>required</rfc2119> keyword in the above rules).
            For example, the error is raised if the primary format token contains a digit but does
            not match the required regular expression.</p></def></gitem><gitem><label>Notes</label><def><note><olist><item><p>Note the careful distinction between conditions that are errors and conditions where
               fallback occurs. The principle is that an error in the syntax of the format picture will
               be reported by all processors, while a construct that is recognized by some
               implementations but not others will never result in an error, but will instead cause a
               fallback representation of the integer to be used.</p></item><item><p>The following notes apply when a <var>digit-pattern</var> is used:</p><olist><item><p>If <var>grouping-separator-signs</var>
                     appear at regular intervals within the format token, then the sequence is extrapolated to
                     the left, so grouping separators will be used in the formatted number at every
                     multiple of <var>N</var>. For example, if the format token is <code nobreak="false">0'000</code>
                     then the number one million will be formatted as <code nobreak="false">1'000'000</code>, while the
                     number fifteen will be formatted as <code nobreak="false">0'015</code>.</p></item><item><p>The only purpose of <var>optional-digit-signs</var> is to mark the position of
                     <var>grouping-separator-signs</var>. For example, if the format token is
                     <code nobreak="false">#'##0</code> then the number one million will be formatted as
                     <code nobreak="false">1'000'000</code>, while the number fifteen will be formatted as
                     <code nobreak="false">15</code>. A grouping separator is included in the formatted number only
                     if there is a digit to its left, which will only be the case if either (a) the
                     number is large enough to require that digit, or (b) the number of
                     <var>mandatory-digit-signs</var> in the format token requires insignificant
                     leading zeros to be present.</p></item><item><p>Grouping separators are <emph>not</emph> designed for effects such as
                     formatting a US telephone number as <code nobreak="false">(365)123-9876</code>. In general they are not 
                     suitable for such purposes because (a) only single characters are allowed, and (b) they
                     cannot appear at the beginning or end of the number.</p></item><item><p>Numbers will never be truncated. Given the <var>digit-pattern</var>
                        <code nobreak="false">01</code>, the number three hundred will be output as <code nobreak="false">300</code>,
                     despite the absence of any <var>optional-digit-sign</var>.</p></item></olist></item><item><p>The following notes apply when ordinal numbering is selected using the <code nobreak="false">o</code> modifier.</p><p>In some languages, the form of numbers (especially ordinal numbers) varies depending 
                  on the grammatical context: they may have different genders and may decline with the 
                  noun that they qualify. In such cases the string appearing in parentheses after the 
                  letter <code nobreak="false">c</code> or <code nobreak="false">o</code> may be used to indicate the variation of the 
                  cardinal or ordinal number required.</p><p>The way in which the variation is indicated will depend on the conventions of the language.</p><p>For inflected languages that vary the ending of the word, the approach recommended 
                     in the previous version of this specification was to indicate the required ending, 
                     preceded by a hyphen: for example in German, appropriate values might be 
                     <code nobreak="false">o(-e)</code>, <code nobreak="false">o(-er)</code>, <code nobreak="false">o(-es)</code>, <code nobreak="false">o(-en)</code>. 
                  </p><p>Another approach, which might usefully be adopted by an implementation based on the 
                     open-source ICU localization library <bibref ref="ICU"/>, or any other library making use of the 
                     Unicode Common Locale Data Repository <bibref ref="CLDR"/>, is to allow the value in parentheses 
                     to be the name of a registered numbering rule set for the language in question, 
                     conventionally prefixed with a percent sign: for example, 
                     <code nobreak="false">o(%spellout-ordinal-masculine)</code>, or <code nobreak="false">c(%spellout-cardinal-year)</code>.
                  </p></item><item><p>The following notes apply when the primary format token is neither a <var>digit-pattern</var>
               nor one of the seven other defined format tokens (A, a, i, I, w, W, Ww), but is an arbitrary token
               representing the number 1:</p><p>Unexpected results may occur for traditional numbering. For example, in an
                  implementation that supports traditional numbering system in Greek, the example
                     <code nobreak="false">format-integer(19, "α;t")</code> might return <code nobreak="false">δπιιιι</code> or
                     <code nobreak="false">ιθ</code>, depending upon whether the ancient acrophonic or late antique
                  alphabetic system is supported. </p><p>Unexpected results may also occur for alphabetic numbering. For example, in an
                  implementation that supports alphabetic numbering system in Greek, someone
                  writing <code nobreak="false">format-integer(19, "α;a")</code> might expect the nineteenth Greek
                  letter, <char>U+03C4</char>, but the implementation might return the eighteenth one, 
                  <char>U+03C3</char>, because the latter is the nineteenth item in the sequence of 
                  lowercase Greek letters in Unicode (the sequence is interrupted because of the final 
                  form of the sigma, <char>U+03C2</char>). Because Greek never had a final capital sigma, 
                  Unicode has marked <char>U+03A2</char>, the eighteenth codepoint in the sequence of Greek capital 
                  letters, as reserved, to ensure that every Greek uppercase letter is always 32 codepoints 
                  less than its lowercase counterpart. Therefore, someone writing 
                  <code nobreak="false">format-integer(18, "Α;a")</code> might expect the eighteenth Greek capital letter, 
                  <char>U+03A3</char>, but an implementation might return <char>U+03A2</char>, 
                  the eighteenth position 
                  in the sequence of Greek capital letters, but unassigned to any character. </p></item></olist></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(123, '0000')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"0123"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(123, 'w')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Depending on the default language, the expression might return
               the string <code nobreak="false">"one hundred and twenty-three"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(21, '1;o', 'en')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"21st"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(14, 'Ww;o(-e)', 'de')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>If supported, might return the string <code nobreak="false">"Vierzehnte"</code>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">(1 to 10) ! format-integer(., "1;o(-º)", language:="it")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>This requests ordinal numbering in Italian: if supported, 
                  this should produce the sequence: <code nobreak="false">1º 2º 3º 4º ...</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">(1 to 10) ! format-integer(., "Ww;o", language:="it")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>This requests ordinal numbering in Italian, spelled out
                  as words: if supported, 
                  this should produce the sequence: <code nobreak="false">Primo Secondo Terzo Quarto Quinto ...</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(7, 'a')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"g"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(27, 'a')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"aa"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(57, 'I')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"LVII"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(1234, '#;##0;')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1;234"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(1234, '16^xxxx')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"04d2"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(1234, '16^X')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"4D2"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(12345678, '16^xxxx_xxxx')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"00bc_614e"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(12345678, '16^#_xxxx')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"bc_614e"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(255, '2^xxxx xxxx')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1111 1111"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(1023, '32^XXXX')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"00VV"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(1023, '10^XXXX')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1023"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(1023, '10^00')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"10^23"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(-5, '001')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"-005"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(-5, 'a')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"-e"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">format-integer(-12, '16^XX')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"-0C"</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="formatting-numbers"><head>Formatting numbers</head><p>This section defines a function for formatting decimal and floating point numbers.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:format-number</code></td><td rowspan="1" colspan="1">Returns a string containing a number formatted according to a given picture string
            and decimal format.</td></tr></tbody></table><note><p>This function can be used to format any numeric quantity, including an integer. For integers, however,
		         the <function>fn:format-integer</function> function offers additional possibilities. Note also that the picture
		         strings used by the two functions are not 100% compatible, though they share some options in common.</p></note><div3 id="defining-decimal-format"><head>Defining a decimal format</head><p>Decimal formats are defined in the static context, and the way they are defined is therefore outside the scope
of this specification. XSLT and XQuery both provide custom syntax for creating a decimal format.</p><p>The static context provides a set of decimal formats. One of the decimal formats is unnamed, the others (if any)
   are identified by a QName. There is always an unnamed decimal format available, but its contents are 
   <termref def="implementation-defined"/>.</p><p>Each decimal format provides a set of named properties.</p><note><p>A phrase such as "The <xtermref spec="XP40" ref="id-static-decimal-format-minus-sign">minus-sign</xtermref> character" is to be read as 
   “the character assigned to the <xtermref spec="XP40" ref="id-static-decimal-format-minus-sign">minus-sign</xtermref>
property in the relevant decimal format”.</p></note><p><termdef id="dt-decimal-digit-family" term="digit family">The <term>decimal digit family</term> of a decimal format 
is the sequence of ten digits with
consecutive Unicode <termref def="codepoint">codepoints</termref> starting with the character that is the value of the 
   <xtermref spec="XP40" ref="id-static-decimal-format-zero-digit">zero-digit</xtermref> property.</termdef></p><p><termdef id="dt-optional-digit-character" term="optional digit character">The <term>optional digit character</term> is
                  the character that is the value of the 
                  <xtermref spec="XP40" ref="id-static-decimal-format-digit">digit</xtermref> property.</termdef></p><p>For any decimal format, the properties
representing characters used in a <termref def="dt-picture-string">picture string</termref>
   must have distinct values. These properties are <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref> ,
   <xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref>, 
   <xtermref spec="XP40" ref="id-static-decimal-format-exponent-separator">exponent-separator</xtermref>,
   <xtermref spec="XP40" ref="id-static-decimal-format-percent">percent</xtermref>, <xtermref spec="XP40" ref="id-static-decimal-format-per-mille">per-mille</xtermref>,
<xtermref spec="XP40" ref="id-static-decimal-format-digit">digit</xtermref>, and <xtermref spec="XP40" ref="id-static-decimal-format-pattern-separator">pattern-separator</xtermref>.
   Furthermore, none of these properties may be equal to any <termref def="character">character</termref> in the 
<termref def="dt-decimal-digit-family">decimal digit family</termref>.

</p></div3><div3 id="func-format-number"><head>fn:format-number</head><changes><change issue="780" PR="925" date="2024-01-09">The decimal format name can now be supplied 
            as a value of type <code nobreak="false">xs:QName</code>,
            as an alternative to supplying a lexical QName as an instance of <code nobreak="false">xs:string</code>.</change><change issue="340 1138" PR="1049 1151" date="2024-03-05">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.</change><change issue="1048" PR="1250" date="2024-06-11">For selected properties including <code nobreak="false">percent</code> and <code nobreak="false">exponent-separator</code>,
         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.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a string containing a number formatted according to a given picture string
            and decimal format.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="format-number" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:numeric?"/><arg name="picture" type="xs:string"/><arg name="options" type="(xs:string | map(*))?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		decimal formats, and namespaces.
	</p></def></gitem><gitem><label>Rules</label><def><p>The function formats <code nobreak="false">$value</code> as a string using the <termref def="dt-picture-string">picture string</termref> specified by the
               <code nobreak="false">$picture</code> argument and a decimal format.</p><p>The <code nobreak="false">$value</code> argument may be of any numeric data type
            (<code nobreak="false">xs:double</code>, <code nobreak="false">xs:float</code>, <code nobreak="false">xs:decimal</code>, or their
            subtypes including <code nobreak="false">xs:integer</code>). Note that if an <code nobreak="false">xs:decimal</code> is
            supplied, it is not automatically converted to an <code nobreak="false">xs:double</code>, as such
            conversion can involve a loss of precision.</p><p>If the supplied value of the <code nobreak="false">$value</code> argument is the empty sequence, the
            function behaves as if the supplied value were the <code nobreak="false">xs:double</code> value
               <code nobreak="false">NaN</code>.</p><p>If <code nobreak="false">$options</code> is the empty map, then the number is
            formatted using the properties of the unnamed decimal format in the static context.</p><p>For backwards compatibility reasons, the decimal format can be supplied as
         an instance of <code nobreak="false">xs:string</code>. If the value of the <code nobreak="false">$options</code>
         argument is an <code nobreak="false">xs:string</code>, then its value
                  <rfc2119>must</rfc2119> be a string which after removal of leading
                  and trailing whitespace is in the form of an <code nobreak="false">EQName</code>
                  as defined in the XPath 4.0 grammar, that is one of the following:</p><ulist><item><p>A lexical QName, which is expanded using the statically known namespaces.
                        The default namespace is not used (no prefix means no namespace).</p></item><item><p>A <code nobreak="false">URIQualifiedName</code> using the syntax <code nobreak="false">Q{uri}local</code>,
                        where the URI can be zero-length to indicate a name in no namespace.</p></item></ulist><p>The effective value of the <code nobreak="false">$options</code> argument is then the map
         <code nobreak="false">{ 'format-name': $FN }</code> where <code nobreak="false">$FN</code> is the
            <code nobreak="false">xs:QName</code> result of expanding this <code nobreak="false">EQName</code>.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows. 
            The <termref def="option-parameter-conventions"/> apply. The detailed rules
            for the interpretation of each option appear later.</p><p>In the table, the type <code nobreak="false">xs:string (: matching '.' :)</code>
            represents a single-character string, that is, a restriction of <code nobreak="false">xs:string</code>
            with the facet <code nobreak="false">pattern="."</code>, while the type 
            <code nobreak="false">xs:string (: matching '.|.:.*' :)</code> indicates a string
            that is either a single character, or a single character followed by <char>U+003A</char>
            followed by an arbitrary string. Such a property identifies two values: a single
            character called the <term>marker</term>, which is used to represent the property
            in the picture string; and an arbitrary string called the <term>rendition</term>
            which is used to represent in the property in the result string. In the absence of the colon
            the single character value is used both as the marker and the rendition.</p><p>The default value for absent options (other than
            <code nobreak="false">format-name</code>) is taken from a decimal format in the static context; the default
            values shown in the table are the values used if no specific value is assigned in the
            static context.
         </p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="format-name" type="(xs:NCName | xs:QName)?" occur="opt"/><arg name="decimal-separator" type="xs:string (: matching '.|.:.*' :)" occur="opt"/><arg name="grouping-separator" type="xs:string (: matching '.|.:.*' :)" occur="opt"/><arg name="exponent-separator" type="xs:string (: matching '.|.:.*' :)" occur="opt"/><arg name="infinity" type="xs:string" occur="opt"/><arg name="minus-sign" type="xs:string" occur="opt"/><arg name="NaN" type="xs:string" occur="opt"/><arg name="percent" type="xs:string (: matching '.|.:.*' :)" occur="opt"/><arg name="per-mille" type="xs:string (: matching '.|.:.*' :)" occur="opt"/><arg name="zero-digit" type="xs:string (: matching '.' :)" occur="opt"/><arg name="digit" type="xs:string (: matching '.' :)" occur="opt"/><arg name="pattern-separator" type="xs:string (: matching '.' :)" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">format-name?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
                  The name of a decimal format in the static context; if absent, the unnamed
                     decimal format in the static context is used. An <code nobreak="false">xs:NCName</code>
                     represents the local part of an <code nobreak="false">xs:QName</code> in no namespace.
               <ulist><item><p><term>Type: </term><code nobreak="false">(xs:NCName | xs:QName)?</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">decimal-separator?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The <term>marker</term> used to represent the decimal point 
                  in the picture string, and the <term>rendition</term> of the decimal point
                  in the formatted number.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string (: matching '.|.:.*' :)</code></p></item><item><p><term>Default: </term><code nobreak="false">"."</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">grouping-separator?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The <term>marker</term> used to separate groups of digits 
                  in the picture string, and the <term>rendition</term>
                  of the grouping separator in the formatted number.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string (: matching '.|.:.*' :)</code></p></item><item><p><term>Default: </term><code nobreak="false">","</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">exponent-separator?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The <term>marker</term> used to separate the mantissa from the exponent
                  in scientific notation in the picture 
                  string, and the <term>rendition</term> of the exponent separator
                  in the formatted number.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string (: matching '.|.:.*' :)</code></p></item><item><p><term>Default: </term><code nobreak="false">"e"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">infinity?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The string used to represent the value positive or negative infinity 
                  in the formatted number.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">"Infinity"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">minus-sign?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The string used as a minus sign in the formatted number if 
                  there is no subpicture for formatting negative numbers.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">"-"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">NaN?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The string used to represent the value <code nobreak="false">NaN</code> 
                  in the formatted number.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">"NaN"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">percent?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The <term>marker</term> used to indicate the presence of a percent sign 
                  in the picture string, and the <term>rendition</term> of the percent sign 
                  in the formatted number.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string (: matching '.|.:.*' :)</code></p></item><item><p><term>Default: </term><code nobreak="false">"%"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">per-mille?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><term>marker</term> used to indicate the presence of a per-mille sign 
                  in the picture string, and the <term>rendition</term> of the per-mille sign 
                  in the formatted number.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string (: matching '.|.:.*' :)</code></p></item><item><p><term>Default: </term><code nobreak="false">"‰" (0x2030)</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">zero-digit?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Defines the characters used in the picture string to represent a mandatory digit: 
                  for example, if the zero-digit is <code nobreak="false">0</code> then any of the
                  digits <code nobreak="false">0</code> to <code nobreak="false">9</code> may be used (interchangeably) 
                  in the picture string to represent a mandatory digit,
                  and in the formatted number the characters <code nobreak="false">0</code> to <code nobreak="false">9</code> 
                  will be used to represent the digits zero to nine. The value must be
                  a character in Unicode category Nd with decimal digit value 0 (zero).
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:string (: matching '.' :)</code></p></item><item><p><term>Default: </term><code nobreak="false">"0"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">digit?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The character used in the picture string to represent 
                  an optional digit.
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:string (: matching '.' :)</code></p></item><item><p><term>Default: </term><code nobreak="false">"#"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">pattern-separator?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">The character used in the picture string to separate the positive 
                  and negative subpictures.
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:string (: matching '.' :)</code></p></item><item><p><term>Default: </term><code nobreak="false">";"</code></p></item></ulist></td></tr></tbody></table><p>A base decimal format is established as follows:</p><ulist><item><p>If the <code nobreak="false">format-name</code> option is present, then 
               the decimal format in the static context identified by this name.</p></item><item><p>Otherwise, the unnamed decimal format in the static context.</p></item></ulist><p>The base decimal format is then modified using the other entries in the
         supplied <code nobreak="false">$options</code> map. 
         </p><p>The evaluation of the <function>fn:format-number</function> function takes place in two
            phases, an analysis phase described in <specref ref="analyzing-picture-string"/> and a
            formatting phase described in <specref ref="formatting-the-number"/>.</p><p>The analysis phase takes as its inputs the <termref def="dt-picture-string">picture
               string</termref> and the variables derived from the relevant decimal format in the
            static context, and produces as its output a number of variables with defined values.
            The formatting phase takes as its inputs the number to be formatted and the variables
            produced by the analysis phase, and produces as its output a string containing a
            formatted representation of the number.</p><p>The result of the function is the formatted string representation of the supplied
            number.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DF" code="1280"/>
            <phrase diff="chg" at="A">if 
            the <code nobreak="false">$options</code> argument is supplied as an <code nobreak="false">xs:string</code>
            that is</phrase> neither a valid lexical QName nor a
            valid <code nobreak="false">URIQualifiedName</code>, or if it uses a prefix that is not found in the
            statically known namespaces; or if the static context does not contain a declaration of
            a decimal format with a matching expanded QName; or if <code nobreak="false">$options?format-name</code>
            is present and the static context does
            not contain a declaration of a decimal format whose name matches <code nobreak="false">$options?format-name</code>.
            If the processor is able to detect the
            error statically (for example, when the argument is supplied as a string literal), then
            the processor <rfc2119>may</rfc2119> optionally signal this as a static error.</p><p>A dynamic error is raised <errorref class="DF" code="1290"/> if a value of
            <code nobreak="false">$format</code> is not valid for the associated property, or if the properties
            of the decimal format resulting from a supplied <code nobreak="false">$options</code>
            map do not have distinct values.</p></def></gitem><gitem><label>Notes</label><def><note><p>A string is an ordered sequence of characters, and this specification 
            uses terms such as “left” and “right”, “preceding” and “following” in relation to this ordering, 
            irrespective of the position of the characters when visually rendered on some output medium. 
            Both in the picture string and in the result string, digits with higher significance (that is, 
            representing higher powers of ten) always precede digits with lower significance, even when 
            the rendered text flow is from right to left.</p><p>In previous versions of XSLT and XQuery, decimal formats were typically defined in the
         static context using custom declarations (<code nobreak="false">&lt;xsl:decimal-format&gt;</code> in XSLT,
         <code nobreak="false">declare decimal-format</code> in XQuery) and then selected by name in a call on
         <function>fn:format-number</function>. This mechanism remains available, but in 4.0, 
            it may be more convenient to dispense with these
            declarations, and instead to define a decimal format as a map bound to a global
            variable, which can be referenced in the <code nobreak="false">$options</code> argument of the 
            <function>fn:format-number</function> call.</p><p>Alternative ways to format an <code nobreak="false">xs:double</code> as a string include:</p><ulist><item><p>Direct casting to string, for example using the constructor function <code nobreak="false">xs:string($number)</code></p></item><item><p>JSON serialization, for example <code nobreak="false">fn:serialize($number, {'method':'json', 'canonical':true()})</code></p></item></ulist><p>In general these will produce different results, for example in the amount of precision that is retained, and
         in the use of exponential (scientific) notation.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>The following examples assume a default decimal format in which the chosen digits are
               the ASCII digits 0-9, the decimal separator is <code nobreak="false">.</code>, the grouping separator is <code nobreak="false">,</code>,
               the minus-sign is <code nobreak="false">-</code>, and the percent-sign is <code nobreak="false">%</code>.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(12345.6, '#,###.00')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"12,345.60"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(12345678.9, '9,999.99')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"12,345,678.90"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(123.9, '9999')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"0124"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(0.14, '01%')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"14%"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(0.14, '01%', { 'percent': '%:pc' })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"14pc"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
format-number(12345, '0.0###^0', { 
   'exponent-separator': '^:×10^' 
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"1.2345×10^4"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(-6, '000')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"-006"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
format-number(1234567.8, '0.000,0', {
   'grouping-separator': '.',
   'decimal-separator': ','
 })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"1.234.567,8"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>The following examples assume the existence of a decimal format named
               <code nobreak="false">de</code> in which the grouping separator is <code nobreak="false">.</code> and the
               decimal separator is <code nobreak="false">,</code>:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(1234.5678, '#.##0,00', { 'format-name': 'de' })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1.234,57"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
format-number(12345, '0,###^0', {
  'format-name': 'de',
  'exponent-separator': '^'
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"1,234^4"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
format-number(12345, '0,###^0', {
  'format-name': 'de',
  'exponent-separator': '^:×10^'
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"1,234×10^4"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>The following examples assume that the exponent separator
               in decimal format <code nobreak="false">fortran</code> is <code nobreak="false">E</code>:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(1234.5678, '00.000E0', 'fortran')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"12.346E2"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(0.234, '0.0E0', 'fortran')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"2.3E-1"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(0.234, '#.00E0', 'fortran')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"0.23E0"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">format-number(0.234, '.00E0', 'fortran')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">".23E0"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="syntax-of-picture-string"><head>Syntax of the picture string</head><note><p>This differs from the <code nobreak="false">format-number</code> function previously defined in XSLT 2.0 in that
			   any digit can be used in the picture string to represent a mandatory digit: for example the picture
			   strings <code nobreak="false">"000"</code>, <code nobreak="false">"001"</code>, and <code nobreak="false">"999"</code> are equivalent.
			   The digits will all be from the same decimal digit family,
			   specifically, the sequence of ten consecutive digits starting with the digit assigned to the <var>zero-digit</var> property.
			      This change is to align <code nobreak="false">format-number</code> 
			   (which previously used <code nobreak="false">"000"</code>) with <code nobreak="false">format-dateTime</code> (which used <code nobreak="false">001</code>).</p></note><p>
                  <termdef id="dt-picture-string" term="picture string">The formatting of a 
number is controlled by a <term>picture string</term>. The
                     picture string is a sequence of <termref def="character">characters</termref>, in which the characters
                     assigned to the properties <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref> , 
                     <xtermref spec="XP40" ref="id-static-decimal-format-exponent-separator">exponent-separator</xtermref>, 
                     <xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref>, 
                     <xtermref spec="XP40" ref="id-static-decimal-format-digit">digit</xtermref>, 
                     and <xtermref spec="XP40" ref="id-static-decimal-format-pattern-separator">pattern-separator</xtermref> 
                     and the members of the <termref def="dt-decimal-digit-family">decimal digit family</termref>, are classified as
active characters, and all other characters (including the values of the properties <xtermref spec="XP40" ref="id-static-decimal-format-percent">percent</xtermref> and 
<xtermref spec="XP40" ref="id-static-decimal-format-per-mille">per-mille</xtermref>) are classified as passive characters.</termdef> 

               </p><p>A dynamic error is raised <errorref class="DF" code="1310"/> if the
 <termref def="dt-picture-string">picture string</termref> does not conform to the following rules. 
               Note that in these
rules the words "preceded" and "followed" refer to characters anywhere in the string; they
are not to be read as "immediately preceded" and "immediately followed".</p><ulist><item><p>A picture-string consists either of a sub-picture, or of
        two sub-pictures separated by the <xtermref spec="XP40" ref="id-static-decimal-format-pattern-separator">pattern-separator</xtermref> character. A picture-string
        <rfc2119>must not</rfc2119> contain more than one instance of the <xtermref spec="XP40" ref="id-static-decimal-format-pattern-separator">pattern-separator</xtermref> character. 
                        If the picture-string contains two
        sub-pictures, the first is used for positive and unsigned zero values and the second for negative values.</p></item><item><p>A sub-picture <rfc2119>must not</rfc2119> contain more than one instance of the 
                        <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref> character.</p></item><item><p>A sub-picture <rfc2119>must not</rfc2119> contain more than one instance of the 
                        <xtermref spec="XP40" ref="id-static-decimal-format-percent">percent</xtermref> or
        <xtermref spec="XP40" ref="id-static-decimal-format-per-mille">per-mille</xtermref> characters, and it <rfc2119>must not</rfc2119> contain one of each.</p></item><item><p>The <var>mantissa part</var> of a
                        sub-picture (defined below) <rfc2119>must</rfc2119> contain at least one character that is either 
                        an <termref def="dt-optional-digit-character">optional digit character</termref>
                        or a member of the <termref def="dt-decimal-digit-family">decimal digit family</termref>.</p></item><item><p>A sub-picture <rfc2119>must not</rfc2119> contain a passive character that is preceded by
        an active character and that is followed by another active character.</p></item><item><p>A sub-picture <rfc2119>must not</rfc2119> contain a <xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref> 
                        character that appears adjacent to                        
                         a <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character, 
                         or in the absence of a 
                           <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character, 
                           at the end of the <var>integer part</var>.</p></item><item><p>A sub-picture <rfc2119>must not</rfc2119> contain two adjacent instances of the <xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref> character.</p></item><item><p>The <var>integer part</var> of a sub-picture (defined below) <rfc2119>must not</rfc2119> contain 
                        a member of the <termref def="dt-decimal-digit-family">decimal digit family</termref> 
					 that is followed by
					 an instance of the <termref def="dt-optional-digit-character">optional digit character</termref>. 
                        The <var>fractional part</var> of a sub-picture (defined below) <rfc2119>must not</rfc2119> contain an instance of the 
                        <termref def="dt-optional-digit-character">optional digit character</termref>
                        that is followed by a member of the <termref def="dt-decimal-digit-family">decimal digit family</termref>.</p></item><item><p>A character that matches the <xtermref spec="XP40" ref="id-static-decimal-format-exponent-separator">exponent-separator</xtermref> property
                  is treated as an <var>exponent-separator-sign</var> if it is both preceded and followed
                  within the sub-picture by an active character. Otherwise, it is treated as a passive character. 
                  A sub-picture <rfc2119>must not</rfc2119> contain more than one character that is treated as an <var>exponent-separator-sign</var>.
                  </p></item><item><p>A sub-picture that contains a <xtermref spec="XP40" ref="id-static-decimal-format-percent">percent</xtermref> or
                     <xtermref spec="XP40" ref="id-static-decimal-format-per-mille">per-mille</xtermref> character <rfc2119>must not</rfc2119> contain a character treated as an
                     <var>exponent-separator-sign</var>.</p></item><item><p>If a sub-picture contains a character treated as an
                     <var>exponent-separator-sign</var> then this <rfc2119>must</rfc2119> be followed by
                     one or more characters that are members of the <termref def="dt-decimal-digit-family">decimal digit family</termref>,
                     and it <rfc2119>must not</rfc2119> be followed by any active character
                     that is not a member of the <termref def="dt-decimal-digit-family">decimal digit family</termref>.</p></item></ulist><p>The <var>mantissa part</var> of the sub-picture is defined as the part that appears
               to the left of the <var>exponent-separator-sign</var> if there is one, or the entire
               sub-picture otherwise. The <var>exponent part</var> of the subpicture is defined as
                  the part that appears to the right of the <var>exponent-separator-sign</var>;
                  if there is no <var>exponent-separator-sign</var> then the <var>exponent part</var>
               is absent.</p><p>The <var>integer part</var> of the sub-picture is defined as the part that
                  appears to the left of the <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character if there is one, or the entire
                  <var>mantissa part</var> otherwise.</p><p>The <var>fractional part</var> of the sub-picture is defined as that
                  part of the <var>mantissa part</var> that
                  appears to the right of the <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character if there is one, or the part that appears
                  to the right of the rightmost active character otherwise. The fractional part may be zero-length.</p></div3><div3 id="analyzing-picture-string"><head>Analyzing the picture string</head><p>This phase of the algorithm analyzes 
                  the <termref def="dt-picture-string">picture string</termref> and the properties from the selected
decimal format in the static context, and it has the effect
of setting the values of various variables, which are used in the
subsequent formatting phase. These variables are listed below.
Each is shown with its initial setting and its datatype.
					</p><p>Several variables are associated with each sub-picture. If there are
two sub-pictures, then these rules are applied to one sub-picture to obtain the values
that apply to positive and unsigned zero numbers, and to the other to obtain the values that apply
to negative numbers. If there is only one sub-picture, then the values for both cases
are derived from this sub-picture.</p><p>The variables are as follows:</p><ulist><item><p>The <var>integer-part-grouping-positions</var> is a sequence of integers
representing the positions of grouping separators within the integer part of the
sub-picture. For each <xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref> character that appears within the
integer part of the sub-picture, this sequence contains an integer that is equal
to the total number of <termref def="dt-optional-digit-character">optional digit character</termref> and <termref def="dt-decimal-digit-family">decimal digit family</termref>
characters that appear within the integer part of the sub-picture and to the right of the 
<xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref> character.</p><p>The grouping is defined to be <term>regular</term> if the following conditions apply:</p><olist><item><p>There is an least one grouping-separator in the integer part of the sub-picture.</p></item><item><p>There is a positive integer <var>G</var> (the grouping size) such that the position of every grouping-separator
                        in the integer part of the sub-picture is a positive integer multiple of <var>G</var>.</p></item><item><p>Every position in the integer part of the sub-picture that is a positive integer multiple of <var>G</var>
                        is occupied by a grouping-separator.</p></item></olist><p>If the grouping is regular, then the <var>integer-part-grouping-positions</var> sequence contains all
integer multiples of <var>G</var> as far as necessary to accommodate the largest 
possible number.</p></item><item><p>The <var>minimum-integer-part-size</var> is an integer indicating the minimum number of digits that will
 appear to the left of the <var>decimal-separator</var> character. It is initially set to 
 the number of <termref def="dt-decimal-digit-family">decimal digit family</termref> characters found in the integer part of the sub-picture,
                        but may be adjusted as described below. </p><note><p>There is no maximum integer part size. All significant digits in the integer part of the
                           number will be displayed, even if this exceeds the number of <termref def="dt-optional-digit-character">optional digit character</termref> and
 <termref def="dt-decimal-digit-family">decimal digit family</termref> characters in the subpicture.</p></note></item><item><p>The <var>scaling factor</var> is a non-negative integer used to determine the scaling of the mantissa
                        in exponential notation. It is set to the number of <termref def="dt-decimal-digit-family">decimal digit family</termref> 
                        characters found in the integer part of the sub-picture.</p></item><item><p>The <var>prefix</var> is set to contain all passive characters
in the sub-picture to the left of the leftmost active character.
If the picture string contains only one sub-picture, 
the <var>prefix</var> 
for the negative sub-picture is set by concatenating the <xtermref spec="XP40" ref="id-static-decimal-format-minus-sign">minus-sign</xtermref> 
character and the <var>prefix</var> for the positive sub-picture (if any),
in that order.</p></item><item><p>The <var>fractional-part-grouping-positions</var> is a sequence of integers
representing the positions of grouping separators within the fractional part of the
sub-picture. For each <xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref> character that appears within the
fractional part of the sub-picture, this sequence contains an integer that is equal
to the total number of <termref def="dt-optional-digit-character">optional digit character</termref> and <termref def="dt-decimal-digit-family">decimal digit family</termref> 
characters that appear within the fractional part of the sub-picture and to the left of the 
<xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref> character.</p><note><p>There is no need to extrapolate grouping positions on the fractional side,
                     because the number of digits in the output will never exceed the number of 
                        <termref def="dt-optional-digit-character">optional digit character</termref> and <termref def="dt-decimal-digit-family">decimal digit family</termref> characters
                     in the fractional part of the sub-picture.</p></note></item><item><p>The <var>minimum-fractional-part-size</var> is set to the number of 
<termref def="dt-decimal-digit-family">decimal digit family</termref> characters found in the fractional part of the sub-picture.</p></item><item><p>The <var>maximum-fractional-part-size</var> is set to the total number of 
                        <termref def="dt-optional-digit-character">optional digit character</termref> and 
                        <termref def="dt-decimal-digit-family">decimal digit family</termref> characters found 
                        in the fractional part of the sub-picture.</p></item><item><p>If the effect of the above rules is that <var>minimum-integer-part-size</var> and 
                        <var>maximum-fractional-part-size</var> are both zero, then an adjustment is applied as follows:</p><ulist><item><p>If an exponent separator is present then:</p><ulist><item><p><var>minimum-fractional-part-size</var> is changed to 1 (one).</p></item><item><p><var>maximum-fractional-part-size</var> is changed to 1 (one).</p></item></ulist><note><p>This has the effect that with the picture <code nobreak="false">#.e9</code>, the value <code nobreak="false">0.123</code> is formatted as <code nobreak="false">0.1e0</code></p></note></item><item><p>Otherwise:</p><ulist><item><p><var>minimum-integer-part-size</var> is changed to 1 (one).</p></item></ulist><note><p>This has the effect that with the picture <code nobreak="false">#</code>, the value <code nobreak="false">0.23</code> is formatted
                              as <code nobreak="false">0</code></p></note></item></ulist></item><item><p>If all the following conditions are true:</p><ulist><item><p>An exponent separator is present</p></item><item><p>The <var>minimum-integer-part-size</var> is zero</p></item><item><p>There is at least one <termref def="dt-optional-digit-character">optional digit character</termref> 
                           in the integer part of the sub-picture</p></item></ulist><p>then the <var>minimum-integer-part-size</var> is changed to 1 (one).</p><note><p>This has the effect that with the picture <code nobreak="false">.9e9</code>, the value <code nobreak="false">0.1</code> is formatted
                        as <code nobreak="false">.1e0</code>, while with the picture <code nobreak="false">#.9e9</code>, it is formatted as <code nobreak="false">0.1e0</code></p></note></item><item><p>If (after making the above adjustments) the <var>minimum-integer-part-size</var> and the 
                        <var>minimum-fractional-part-size</var> are both zero, then the <var>minimum-fractional-part-size</var> is set to 1 (one).</p></item><item><p>The <var>minimum-exponent-size</var> is set to the number of 
                        <termref def="dt-decimal-digit-family">decimal digit family</termref> characters found in the exponent part of the sub-picture
                     if present, or zero otherwise.</p><note><p>The rules for the syntax of the picture string ensure that if an exponent
                        separator is present, then the <var>minimum-exponent-size</var> will always be greater than zero.</p></note></item><item><p>The <var>suffix</var> is set to contain all passive characters to the right of the rightmost
active character in the sub-picture.</p></item></ulist><note><p>If there is only one sub-picture, then all variables
for positive numbers and negative numbers will be the same, except for  
<var>prefix</var>: the prefix for negative numbers will 
be preceded by the <xtermref spec="XP40" ref="id-static-decimal-format-minus-sign">minus-sign</xtermref> character.</p></note></div3><div3 id="formatting-the-number"><head>Formatting the number</head><p>This section describes the second phase of processing of the
<function>fn:format-number</function> function. This phase takes as input a number to be formatted
(referred to as the <emph>input number</emph>), and the variables set up by
analyzing the decimal format in the static context and the
<termref def="dt-picture-string">picture string</termref>, as described above.
 The result of this phase is a string, which forms the return value of 
the <function>fn:format-number</function> function.</p><p>The algorithm for this second stage of processing is as follows:</p><olist><item><p>If the input number is <code nobreak="false">NaN</code> (not a number), the result is the 
							 value of the <xtermref spec="XP40" ref="id-static-decimal-format-NaN">pattern separator</xtermref> property (with no
<var>prefix</var> or <var>suffix</var>).</p></item><item><p>In the rules below, the positive sub-picture and its associated variables are used 
							 if the input number is positive, and the negative sub-picture and its associated
                      variables are used if it is negative. For <code nobreak="false">xs:double</code> and <code nobreak="false">xs:float</code>,
                      negative zero is taken as negative, positive zero as positive. For <code nobreak="false">xs:decimal</code>
                     and <code nobreak="false">xs:integer</code>, the positive sub-picture is used for zero.</p></item><item><p>The <var>adjusted number</var> is determined as follows:</p><ulist><item><p>If the sub-picture contains a <xtermref spec="XP40" ref="id-static-decimal-format-percent">percent</xtermref> character, 
                           the <var>adjusted number</var> is the input number multiplied by 100.</p></item><item><p>If the sub-picture contains a <xtermref spec="XP40" ref="id-static-decimal-format-per-mille">per-mille</xtermref> character, 
                           the <var>adjusted number</var> is the input number multiplied by 1000.</p></item><item><p>Otherwise, the <var>adjusted number</var> is the input number.</p></item></ulist><p>If the multiplication causes numeric overflow, no error occurs, and the 
                        <var>adjusted number</var> is positive or negative infinity as appropriate.</p></item><item><p>If the <var>adjusted number</var> is positive or negative infinity, the result is the 
                        concatenation of the appropriate <var>prefix</var>, the value of the <xtermref spec="XP40" ref="id-static-decimal-format-infinity">infinity</xtermref> property,
                        and the appropriate <var>suffix</var>.</p></item><item><p>If the <var>minimum exponent size</var> is non-zero, 
                        <phrase diff="add" at="A">and the <var>adjusted number</var> is non-zero,</phrase> 
                        then the <var>adjusted number</var> is scaled to establish a 
                        mantissa <var>M</var> and an integer exponent <var>E</var>. These are chosen 
                        such that all the following conditions are true:</p><ulist><item><p>The primitive type of <var>M</var> is the same as the primitive type of the <var>adjusted number</var> (integer, decimal, float, or double).</p></item><item><p>The value of <var>M</var> multiplied by ten to the power of <var>E</var> 
                              is equal to the <var>adjusted number</var>.</p></item><item><p>The value of <var>M</var> (unless it is zero) 
                           is less than 10<sup>N</sup>, and at least 10<sup>N-1</sup>, where <var>N</var> is the <var>scaling factor</var>.</p></item></ulist><p>If the <var>minimum exponent size</var> is zero, then <var>M</var> is the <var>adjusted number</var> 
                        and there is no <var>exponent</var>.</p><p>If the <var>minimum exponent size</var> is non-zero and the <var>adjusted number</var> is zero,
                        then <var>M</var> is the <var>adjusted number</var> and <var>E</var> is zero.</p></item><item><p>The mantissa <var>M</var> is converted (if necessary) to
 an <code nobreak="false">xs:decimal</code> value <var>M/D</var>,
using an implementation of <code nobreak="false">xs:decimal</code> that imposes no limits on the
<code nobreak="false">totalDigits</code> or <code nobreak="false">fractionDigits</code> facets. 
The value of <var>M/D</var> is chosen such that:</p><ulist><item><p>If the type of <var>M</var> is <code nobreak="false">xs:decimal</code> (including <code nobreak="false">xs:integer</code>),
            then <var>M/D</var> is <var>M</var>.</p></item><item><p>Otherwise:</p><ulist><item><p>The result of converting <var>M/D</var> to the primitive type of <var>M</var>
                  is equal to <var>M</var> under the rules of the <function>atomic-equal</function> function, and</p></item><item><p>Of all the possible values of <var>M/D</var>, the value that is 
                  chosen <rfc2119>should</rfc2119> be one with the smallest possible number of digits
                  not counting leading or trailing zeroes (whether significant or insignificant). </p></item></ulist><p>For example, 1.0 is preferred to 0.9999999999, and 100000000 is preferred to 100000001.</p></item></ulist><p>This value is then
           rounded so that it uses no more than <code nobreak="false">maximum-fractional-part-size</code> digits in
           its fractional part. The <var>rounded number</var> is defined to be the result of
           calling the function <function>fn:round-half-to-even</function> with <var>M/D</var>
           as the first argument and the <code nobreak="false">maximum-fractional-part-size</code> as the second
           argument, again with no limits on the <code nobreak="false">totalDigits</code> or <code nobreak="false">fractionDigits</code> in the
           result.</p></item><item><p>The absolute value of the <var>rounded number</var> is converted to a string in decimal notation, 
                        using the digits in the <termref def="dt-decimal-digit-family">decimal digit family</termref> to 
                        represent the ten decimal digits, and the <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref> 
                        character to separate the integer part and the fractional part. This string must always contain a 
                        <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>, 
                        and it must contain no leading zeroes and no trailing zeroes. The value zero will at this stage be 
                        represented by a <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref> 
                        on its own.</p></item><item><p>If the number of digits to the left of the <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character is less than
<var>minimum-integer-part-size</var>, leading <xtermref spec="XP40" ref="id-static-decimal-format-zero-digit">zero digit</xtermref> 
characters are added to pad out to that size.</p></item><item><p>If the number of digits to the right of the <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character is less than
<var>minimum-fractional-part-size</var>, trailing <xtermref spec="XP40" ref="id-static-decimal-format-zero-digit">zero digit</xtermref> 
characters are added to pad out to that size.</p></item><item><p>For each integer <var>N</var> in the <var>integer-part-grouping-positions</var> list,  
a <xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref> character is inserted into the string immediately
after that digit that appears in the integer part of the number and has <var>N</var> digits
between it and the <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character, if there is such a digit.</p></item><item><p>For each integer <var>N</var> in the <var>fractional-part-grouping-positions</var> list,  
a <xtermref spec="XP40" ref="id-static-decimal-format-grouping-separator">grouping-separator</xtermref> character is inserted into the string immediately
before that digit that appears in the fractional part of the number and has <var>N</var> digits
between it and the <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character, if there is such a digit.</p></item><item><p>If there is no <xtermref spec="XP40" ref="id-static-decimal-format-decimal-separator">decimal-separator</xtermref>  character in the sub-picture, 
or if there are no digits to the right of the 
<var>decimal-separator</var> character in the string, then the
<var>decimal-separator</var> character is removed from the string (it will be the rightmost 
character in the string).</p></item><item><p>If an <var>exponent</var> exists, then the string
                  produced from the <var>mantissa</var> as described above is extended with
                     the following, in order:
                  (a) the <xtermref spec="XP40" ref="id-static-decimal-format-exponent-separator">exponent-separator</xtermref> character; (b) if the <var>exponent</var> is negative,
                  the <xtermref spec="XP40" ref="id-static-decimal-format-minus-sign">minus-sign</xtermref> character; (c) the value of the <var>exponent</var> represented
                  as a decimal integer, extended if necessary with leading zeroes to make it up to
                  the <var>minimum exponent size</var>, using digits taken from the
                  <termref def="dt-decimal-digit-family">decimal digit family</termref>.</p></item><item><p>The result of the function is the concatenation of the appropriate <var>prefix</var>, the 
string conversion of the number as obtained above, and the appropriate <var>suffix</var>.</p></item></olist></div3></div2><div2 id="trigonometry"><head>Trigonometric and exponential functions</head><p>The functions in this section perform trigonometric and other mathematical calculations on <code nobreak="false">xs:double</code> values. They
			are provided primarily for use in applications performing geometrical computation, for example when generating 
			SVG graphics.</p><p>Functions are provided to support the six most commonly used trigonometric calculations: sine, cosine, and tangent, 
			and their inverses arc sine, arc cosine, and arc tangent. Other functions such as secant, cosecant, and cotangent are
			not provided because they are easily computed in terms of these six.</p><p>The functions in this section (with the exception of <code nobreak="false">math:pi</code>) 
		      are specified by reference to <bibref ref="ieee754-2019"/>, where
		   they appear as <emph>Recommended operations</emph> in section 9. IEEE defines
		   these functions for a variety of floating point formats; this specification
		   defines them only for <code nobreak="false">xs:double</code> values. The IEEE specification
		   applies with the following caveats:</p><olist><item><p>IEEE states that the preferred quantum is language-defined. In this
		       specification, it is <termref def="implementation-defined"/>.</p></item><item><p>IEEE states that certain functions should raise the inexact exception if the
		          result is inexact. 
		          In this specification, this exception if it occurs does not
		          result in an error. Any diagnostic information is outside the scope of this
		          specification.</p></item><item><p>IEEE defines various rounding algorithms for inexact results, and states
		          that the choice of rounding direction, and the mechanisms for influencing this choice,
		          are language-defined. In this specification, the rounding direction and any mechanisms for
		          influencing it are <termref def="implementation-defined"/>.</p></item><item><p>Certain operations (such as taking the square root of a negative number)
		          are defined in IEEE to signal the invalid operation exception and return a
		          quiet <code nobreak="false">NaN</code>. In this specification, such operations return <code nobreak="false">NaN</code>
		          and do not raise an error. The same policy applies to operations (such as taking
		          the logarithm of zero) that raise a divide-by-zero exception. Any diagnostic 
		          information is outside the scope of this specification. </p></item><item><p>Operations whose mathematical result is greater than the largest finite <code nobreak="false">xs:double</code>
		          value are defined in IEEE to signal the overflow exception; operations whose mathematical
		          result is closer to zero than the smallest non-zero <code nobreak="false">xs:double</code> value are similarly
		       defined in IEEE to signal the underflow exception. The treatment of these exceptions in
		       this specification is defined in <specref ref="op.numeric"/>.</p></item></olist><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:pi</code></td><td rowspan="1" colspan="1">Returns an approximation to the mathematical constant <var>π</var>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:e</code></td><td rowspan="1" colspan="1">Returns an approximation to the mathematical constant <var>e</var>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:acos</code></td><td rowspan="1" colspan="1">Returns the arc cosine of the argument.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:asin</code></td><td rowspan="1" colspan="1">Returns the arc sine of the argument.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:atan</code></td><td rowspan="1" colspan="1">Returns the arc tangent of the argument.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:atan2</code></td><td rowspan="1" colspan="1">Returns the angle in radians subtended at the origin by the point on a plane with
            coordinates (x, y) and the positive x-axis.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:cos</code></td><td rowspan="1" colspan="1">Returns the cosine of the argument. The argument is an angle in radians.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:cosh</code></td><td rowspan="1" colspan="1">Returns the hyperbolic cosine of the argument.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:exp</code></td><td rowspan="1" colspan="1">Returns the value of <var>e</var><sup>x</sup> where <var>x</var> is the argument value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:exp10</code></td><td rowspan="1" colspan="1">Returns the value of <code nobreak="false">10</code><sup>x</sup>, where <var>x</var> is the supplied argument value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:log</code></td><td rowspan="1" colspan="1">Returns the natural logarithm of the argument.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:log10</code></td><td rowspan="1" colspan="1">Returns the base-ten logarithm of the argument.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:pow</code></td><td rowspan="1" colspan="1">Returns the result of raising the first argument to the power of the second.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:sin</code></td><td rowspan="1" colspan="1">Returns the sine of the argument. The argument is an angle in radians.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:sinh</code></td><td rowspan="1" colspan="1">Returns the hyperbolic sine of the argument.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:sqrt</code></td><td rowspan="1" colspan="1">Returns the non-negative square root of the argument.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:tan</code></td><td rowspan="1" colspan="1">Returns the tangent of the argument. The argument is an angle in radians.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">math:tanh</code></td><td rowspan="1" colspan="1">Returns the hyperbolic tangent of the argument.</td></tr></tbody></table><p/><div3 id="func-math-pi"><head>math:pi</head><glist><gitem><label>Summary</label><def><p>Returns an approximation to the mathematical constant <var>π</var>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="pi" return-type="xs:double" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>This function returns the <code nobreak="false">xs:double</code> value whose lexical representation is
            3.141592653589793e0</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">2 * math:pi()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">6.283185307179586e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">60 * (math:pi() div 180)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Converts an angle of 60 degrees
               to radians. </p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-e"><head>math:e</head><changes><change issue="1196 1216" PR="1205 1230" date="2024-05-14">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns an approximation to the mathematical constant <var>e</var>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="e" return-type="xs:double" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>This function returns the <code nobreak="false">xs:double</code> value whose lexical representation is
            2.718281828459045e0</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(math:e(), 0.05 * 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.161834242728283e0</code></p><p>(approximately)</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-acos"><head>math:acos</head><glist><gitem><label>Summary</label><def><p>Returns the arc cosine of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="acos" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the result is the arc cosine of <code nobreak="false">$value</code>, as defined in the <bibref ref="ieee754-2019"/> specification of the
               <code nobreak="false">acos</code> function applied to 64-bit binary floating point values.
            The result is in the range zero to +<var>π</var> radians.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">invalidOperation</code> exception is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$value</code> is <code nobreak="false">NaN</code>, or if its absolute value is greater than one,
            then the result is <code nobreak="false">NaN</code>.</p><p>In other cases, the result is an <code nobreak="false">xs:double</code> value representing an angle
               <var>θ</var> in radians in the range <code nobreak="false">0</code> &lt;= <var>θ</var> &lt;=
               <code nobreak="false">math:pi()</code>. </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.5707963267948966e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(-0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.5707963267948966e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(1.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(-1.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3.141592653589793e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(2.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:acos(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-asin"><head>math:asin</head><glist><gitem><label>Summary</label><def><p>Returns the arc sine of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="asin" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the result is the arc sine of <code nobreak="false">$value</code> as defined in the <bibref ref="ieee754-2019"/> specification of the
            <code nobreak="false">asin</code> function applied to 64-bit binary floating point values. 
            The result is in the range -<var>π</var>/2 to +<var>π</var>/2 radians. </p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">invalidOperation</code> and <code nobreak="false">underflow</code> exceptions
            is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$value</code> is positive or negative zero, the result is <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> is <code nobreak="false">NaN</code>, or if its absolute value is greater than one,
            then the result is <code nobreak="false">NaN</code>.</p><p>In other cases, the result is an <code nobreak="false">xs:double</code> value representing an angle
               <var>θ</var> in radians in the range <code nobreak="false">-math:pi() div 2</code> &lt;=
               <var>θ</var> &lt;= <code nobreak="false">math:pi() div 2</code>. </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(-0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(1.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.5707963267948966e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(-1.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.5707963267948966e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(2.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:asin(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-atan"><head>math:atan</head><glist><gitem><label>Summary</label><def><p>Returns the arc tangent of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="atan" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the result is the arc tangent of <code nobreak="false">$value</code>, as defined 
            in the <bibref ref="ieee754-2019"/> specification of the
               <code nobreak="false">atan</code> function applied to 64-bit binary floating point values.
            The result is in the range -<var>π</var>/2
            to +<var>π</var>/2 radians.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">underflow</code> exception is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$value</code> is positive or negative zero, the result is <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> is <code nobreak="false">NaN</code> then the result is <code nobreak="false">NaN</code>.</p><p>In other cases, the result is an <code nobreak="false">xs:double</code> value representing an angle
               <var>θ</var> in radians in the range <code nobreak="false">-math:pi() div 2</code> &lt;=
               <var>θ</var> &lt;= <code nobreak="false">math:pi() div 2</code>. </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan(-0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan(1.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.7853981633974483e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan(-1.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.7853981633974483e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.5707963267948966e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.5707963267948966e0</code></p><p>(approximately)</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-atan2"><head>math:atan2</head><glist><gitem><label>Summary</label><def><p>Returns the angle in radians subtended at the origin by the point on a plane with
            coordinates (x, y) and the positive x-axis.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="atan2" return-type="xs:double" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="y" type="xs:double"/><arg name="x" type="xs:double"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The result is the value of <code nobreak="false">atan2(y, x)</code> as defined in the <bibref ref="ieee754-2019"/> specification of the <code nobreak="false">atan2</code> function applied to
            64-bit binary floating point values. The result is in the range -<var>π</var>
            to +<var>π</var> radians.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">underflow</code> exception is defined in <specref ref="op.numeric"/>. The following rules apply when the values are finite and non-zero, 
            (subject to rules for overflow, underflow, and approximation).</p><p>If either argument is <code nobreak="false">NaN</code> then the result is <code nobreak="false">NaN</code>.</p><p diff="chg" at="B">If <code nobreak="false">$x</code> is positive, then  the value of
            <code nobreak="false">atan2($y, $x)</code> is <code nobreak="false">atan($y div $x)</code>.</p><p diff="chg" at="B">If <code nobreak="false">$x</code> is negative, then:</p><ulist diff="chg" at="B"><item><p>If <code nobreak="false">$y</code> is positive, then the value of <code nobreak="false">atan2($y, $x)</code> is 
               <code nobreak="false">atan($y div $x) + <var>π</var></code>.</p></item><item><p>If <code nobreak="false">$y</code> is negative, then the value of <code nobreak="false">atan2($y, $x)</code> is 
               <code nobreak="false">atan($y div $x) - <var>π</var></code>.</p></item></ulist><p>Some results for special values of the arguments are shown in the examples below.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(+0.0e0, 0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(-0.0e0, 0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(+0.0e0, -0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3.141592653589793e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(-0.0e0, -0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-3.141592653589793e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(-1, 0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.5707963267948966e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(+1, 0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.5707963267948966e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(-0.0e0, -1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-3.141592653589793e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(+0.0e0, -1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3.141592653589793e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(-0.0e0, +1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:atan2(+0.0e0, +1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">+0.0e0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-cos"><head>math:cos</head><glist><gitem><label>Summary</label><def><p>Returns the cosine of the argument. The argument is an angle in radians.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="cos" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="radians" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$radians</code> is the empty sequence, the function returns the empty
            sequence.</p><p>If <code nobreak="false">$radians</code> is positive or negative infinity, or <code nobreak="false">NaN</code>,
            then the result is <code nobreak="false">NaN</code>.</p><p>Otherwise the result is the cosine of <code nobreak="false">$radians</code> (which is treated as an angle in
            radians) as defined in the <bibref ref="ieee754-2019"/> specification of the
               <code nobreak="false">cos</code> function applied to 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">invalidOperation</code> exception is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$radians</code> is positive or negative zero, the result is
            <code nobreak="false">$radians</code>.</p><p>If <code nobreak="false">$radians</code>is positive or negative infinity, or <code nobreak="false">NaN</code>,
            then the result is <code nobreak="false">NaN</code>.</p><p>Otherwise the result is always in the range -1.0e0 to +1.0e0</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(-0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(math:pi() div 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(-math:pi() div 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(math:pi())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cos(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-cosh"><head>math:cosh</head><changes><change issue="1196 1216" PR="1205 1230" date="2024-05-14">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the hyperbolic cosine of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="cosh" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty
            sequence.</p><p>Otherwise the result is the hyperbolic cosine of <code nobreak="false">$value</code> as defined in the
            <bibref ref="ieee754-2019"/> specification of the <code nobreak="false">cosh</code> function applied
            to 64-bit binary floating point values. </p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">overflow</code> exception
            is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$value</code> is positive or negative zero, the result is
            <code nobreak="false">1</code>.</p><p>If <code nobreak="false">$value</code> is positive or negative infinity,
            the result is <code nobreak="false">INF</code>.</p><p>If <code nobreak="false">$value</code> is <code nobreak="false">NaN</code>,
            the result is <code nobreak="false">NaN</code>.</p><p>In other cases, the result is an <code nobreak="false">xs:double</code> in the range
            <code nobreak="false">+1.0</code> to <code nobreak="false">INF</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cosh(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:cosh(math:pi())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">11.591953275521519e0</code></p><p>(approximately)</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-exp"><head>math:exp</head><glist><gitem><label>Summary</label><def><p>Returns the value of <var>e</var><sup>x</sup> where <var>x</var> is the argument value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="exp" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the result is the mathematical constant <var>e</var> raised to the power of
               <code nobreak="false">$value</code>, as defined in the <bibref ref="ieee754-2019"/> specification of
            the <code nobreak="false">exp</code> function applied to 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of overflow and underflow is defined in <specref ref="op.numeric"/>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2.7182818284590455e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">7.38905609893065e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(-1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.36787944117144233e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(math:pi())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">23.140692632779267e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-exp10"><head>math:exp10</head><glist><gitem><label>Summary</label><def><p>Returns the value of <code nobreak="false">10</code><sup>x</sup>, where <var>x</var> is the supplied argument value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="exp10" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the result is ten raised to the power of <code nobreak="false">$value</code>, as defined in the
               <bibref ref="ieee754-2019"/> specification of the <code nobreak="false">exp10</code> function applied
            to 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of overflow and underflow is defined in <specref ref="op.numeric"/>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp10(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp10(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp10(1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp10(0.5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3.1622776601683795e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp10(-1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e-1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp10(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp10(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:exp10(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-log"><head>math:log</head><glist><gitem><label>Summary</label><def><p>Returns the natural logarithm of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="log" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the result is the natural logarithm of <code nobreak="false">$value</code>, as defined in the
               <bibref ref="ieee754-2019"/> specification of the <code nobreak="false">log</code> function applied
            to 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of <code nobreak="false">divideByZero</code> and <code nobreak="false">invalidOperation</code> exceptions
            is defined in <specref ref="op.numeric"/>. <phrase>The effect is that if the argument is 
            zero, the result is <code nobreak="false">-INF</code>, and if it is negative, the result is <code nobreak="false">NaN</code></phrase>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('-INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(math:exp(1))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(1.0e-3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-6.907755278982137e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.6931471805599453e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(-1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-log10"><head>math:log10</head><glist><gitem><label>Summary</label><def><p>Returns the base-ten logarithm of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="log10" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the result is the base-10 logarithm of <code nobreak="false">$value</code>, as defined in the
               <bibref ref="ieee754-2019"/> specification of the <code nobreak="false">log10</code> function applied
            to 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of <code nobreak="false">divideByZero</code> and <code nobreak="false">invalidOperation</code> exceptions
            is defined in <specref ref="op.numeric"/>. <phrase>The effect is that if the argument is 
               zero, the result is <code nobreak="false">-INF</code>, and if it is negative, the result is <code nobreak="false">NaN</code></phrase>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('-INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(1.0e3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(1.0e-3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-3.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.3010299956639812e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(-1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:log10(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-pow"><head>math:pow</head><glist><gitem><label>Summary</label><def><p>Returns the result of raising the first argument to the power of the second.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="pow" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="x" type="xs:double?"/><arg name="y" type="xs:numeric"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$x</code> is the empty sequence, the function returns the empty sequence.</p><p>If <code nobreak="false">$y</code> is an instance of <code nobreak="false">xs:integer</code>, the result is
               <code nobreak="false">$x</code> raised to the power of <code nobreak="false">$y</code> as defined in the <bibref ref="ieee754-2019"/> specification of the <code nobreak="false">pown</code> function applied to a
            64-bit binary floating point value and an integer.</p><p>Otherwise <code nobreak="false">$y</code> is cast to an <code nobreak="false">xs:double</code>, 
            and the result is <code nobreak="false">$x</code> raised to the power of
               <code nobreak="false">$y</code> as defined in the <bibref ref="ieee754-2019"/> specification of the
               <code nobreak="false">pow</code> function applied to two 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">divideByZero</code> and <code nobreak="false">invalidOperation</code>
            exceptions is defined in <specref ref="op.numeric"/>. Some of the consequences are
            illustrated in the examples below.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow((), 93.7)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(2, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">8.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-2, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-8.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(2, -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.125e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-2, -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.125e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(2, 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0, 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(xs:double('INF'), 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(xs:double('NaN'), 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-math:pi(), 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0e0, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0e0, 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-0e0, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0, 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0e0, -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0e0, -4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-0e0, -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('-INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0, -4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(16, 0.5e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">4.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(16, 0.25e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0e0, -3.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-0e0, -3.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('-INF')</code></p><p><emph>(Odd-valued whole numbers are treated specially).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0e0, -3.1e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-0e0, -3.1e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0e0, 3.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-0e0, 3.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p><p><emph>(Odd-valued whole numbers are treated specially).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(0e0, 3.1e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-0e0, 3.1e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-1, xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-1, xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(1, xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(1, xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(1, xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-2.5e0, 2.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">6.25e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:pow(-2.5e0, 2.00000001e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-sin"><head>math:sin</head><glist><gitem><label>Summary</label><def><p>Returns the sine of the argument. The argument is an angle in radians.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="sin" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="radians" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$radians</code> is the empty sequence, the function returns the empty
            sequence.</p><p>Otherwise the result is the sine of <code nobreak="false">$radians</code> (which is treated as an angle in
            radians) as defined in the <bibref ref="ieee754-2019"/> specification of the
               <code nobreak="false">sin</code> function applied to 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">invalidOperation</code> and <code nobreak="false">underflow</code> exceptions
            is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$radians</code> is positive or negative zero, the result is
            <code nobreak="false">$radians</code>.</p><p>If <code nobreak="false">$radians</code> is positive or negative infinity, or <code nobreak="false">NaN</code>,
            then the result is <code nobreak="false">NaN</code>.</p><p>Otherwise the result is always in the range -1.0e0 to +1.0e0</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(-0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(math:pi() div 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(-math:pi() div 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(math:pi())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sin(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-sinh"><head>math:sinh</head><changes><change issue="1196 1216" PR="1205 1230" date="2024-05-14">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the hyperbolic sine of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="sinh" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty
            sequence.</p><p>Otherwise the result is the hyperbolic sine of <code nobreak="false">$value</code> as defined in the
            <bibref ref="ieee754-2019"/> specification of the <code nobreak="false">sinh</code> function applied
            to 64-bit binary floating point values. </p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">overflow</code> and <code nobreak="false">underflow</code> exceptions
            is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$value</code> is positive or negative zero, the result is
            <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> is positive or negative infinity, or <code nobreak="false">NaN</code>,
            the result is <code nobreak="false">NaN</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sinh(1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.1752011936438014e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sinh(math:pi())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">11.548739357257748e0</code></p><p>(approximately)</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-sqrt"><head>math:sqrt</head><glist><gitem><label>Summary</label><def><p>Returns the non-negative square root of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="sqrt" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the result is the mathematical non-negative square root of <code nobreak="false">$value</code>
            as defined in the <bibref ref="ieee754-2019"/> specification of the
               <code nobreak="false">squareRoot</code> function applied to 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">invalidOperation</code> exception is defined in <specref ref="op.numeric"/>. The effect is that if the argument is less than zero, the result
            is <code nobreak="false">NaN</code>.</p><p>If <code nobreak="false">$value</code> is positive or negative zero, positive infinity, or
            <code nobreak="false">NaN</code>, then the result is <code nobreak="false">$value</code>. (Negative zero is the only
            case where the result can have negative sign)</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(-0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(1.0e6)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(2.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.4142135623730951e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(-2.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('INF')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:sqrt(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-tan"><head>math:tan</head><glist><gitem><label>Summary</label><def><p>Returns the tangent of the argument. The argument is an angle in radians.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="tan" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="radians" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$radians</code> is the empty sequence, the function returns the empty
            sequence.</p><p>Otherwise the result is the tangent of <code nobreak="false">$radians</code> (which is treated as an angle
            in radians) as defined in the <bibref ref="ieee754-2019"/> specification of the
               <code nobreak="false">tan</code> function applied to 64-bit binary floating point values.</p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">invalidOperation</code> and <code nobreak="false">underflow</code> exceptions
            is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$radians</code> is positive or negative infinity, or <code nobreak="false">NaN</code>,
            then the result is <code nobreak="false">NaN</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(-0.0e0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(math:pi() div 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(-math:pi() div 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-1.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">1 div math:tan(math:pi() div 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p><p>(approximately)</p><p><emph>(Mathematically, <emph>tan(π/2)</emph> is positive infinity. But because <code nobreak="false">math:pi() div 2</code>
                  returns an approximation, the result of <code nobreak="false">math:tan(math:pi() div 2)</code> will be a large
                  but finite number.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">1 div math:tan(-math:pi() div 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">-0.0e0</code></p><p>(approximately)</p><p><emph>(Mathematically, <emph>tan(-π/2)</emph> is negative infinity. But because <code nobreak="false">-math:pi() div 2</code>
                  returns an approximation, the result of <code nobreak="false">math:tan(-math:pi() div 2)</code> will be a large
                  but finite negative number.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(math:pi())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.0e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(xs:double('NaN'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(xs:double('INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tan(xs:double('-INF'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:double('NaN')</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-math-tanh"><head>math:tanh</head><changes><change issue="1196 1216" PR="1205 1230" date="2024-05-14">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the hyperbolic tangent of the argument.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="math" name="tanh" return-type="xs:double?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:double?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty
            sequence.</p><p>Otherwise the result is the hyperbolic tangent of <code nobreak="false">$value</code> as defined in the
            <bibref ref="ieee754-2019"/> specification of the <code nobreak="false">tanh</code> function applied
            to 64-bit binary floating point values. </p></def></gitem><gitem><label>Notes</label><def><note><p>The treatment of the <code nobreak="false">underflow</code> exception
            is defined in <specref ref="op.numeric"/>. </p><p>If <code nobreak="false">$value</code> is positive or negative zero, the result is
            <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> is positive infinity, the result is <code nobreak="false">+1.0</code>.</p><p>If <code nobreak="false">$value</code> is negative infinity, the result is <code nobreak="false">-1.0</code>.</p><p>In other cases, the result is an <code nobreak="false">xs:double</code> in the range
            <code nobreak="false">-1.0</code> to <code nobreak="false">+1.0</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tanh(1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.7615941559557649e0</code></p><p>(approximately)</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">math:tanh(math:pi())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0.99627207622075e0</code></p><p>(approximately)</p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="random-numbers"><head>Random Numbers</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:random-number-generator</code></td><td rowspan="1" colspan="1">Returns a random number generator, which can be used to generate sequences of random numbers.</td></tr></tbody></table><p>The function makes use of the record structure defined in the next section.</p><div3 id="random-number-generator-record"><head>Record fn:random-number-generator-record</head><p>This record type is used to represent the result of a call on
         the <function>fn:random-number-generator</function> function.</p><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Name</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">number</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>An <code nobreak="false">xs:double</code> greater than or equal
               to zero (0.0e0), and less than one (1.0e0).</p><ulist><item><p><term>Type: </term><code nobreak="false">xs:double</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">next</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
               <p>A zero-arity function that can be called to return another random number
            generator.</p>
               <p>The properties of this function are as follows:</p>
               <ulist><item><p>name: absent</p></item><item><p>parameter names: ()</p></item><item><p>signature: <code nobreak="false">() =&gt; random-number-generator-record</code></p></item><item><p>non-local variable bindings: none</p></item><item><p>implementation: implementation-dependent</p></item></ulist>
         <ulist><item><p><term>Type: </term><code nobreak="false">fn() as random-number-generator-record</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">permute</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
               <p>A function with arity 1 (one), which takes an arbitrary sequence
            as its argument, and returns a random permutation of that sequence.</p>
               <p>The properties of this function are as follows:</p>
               <ulist><item><p>name: absent</p></item><item><p>parameter names: <code nobreak="false">"arg"</code></p></item><item><p>signature: <code nobreak="false">(item()*) =&gt; item()*</code></p></item><item><p>non-local variable bindings: none</p></item><item><p>body: implementation-dependent</p></item></ulist>
         <ulist><item><p><term>Type: </term><code nobreak="false">function(item()*) as item()*</code></p></item></ulist></td></tr></tbody></table></div3><div3 id="func-random-number-generator"><head>fn:random-number-generator</head><changes><change>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 <code nobreak="false">xs:double</code> values between 0.01 and 0.1 as there are between 
            0.1 and 1.0).</change></changes><glist><gitem><label>Summary</label><def><p>Returns a random number generator, which can be used to generate sequences of random numbers.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="random-number-generator" return-type-ref="random-number-generator-record" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="seed" type="xs:anyAtomicType?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p diff="chg" at="2022-12-19">The function returns a random number generator. A random number generator is represented as a value of type 
            <code nobreak="false">random-number-generator-record</code>, defined in
         <specref ref="random-number-generator-record"/>.</p><p>Calling the <function>fn:random-number-generator</function> function with
            the empty sequence as <code nobreak="false">$seed</code> is equivalent to calling the single-argument
            form of the function with an implementation-dependent seed.</p><p>If a <code nobreak="false">$seed</code> is supplied, it may be an atomic item of any type.</p><p>Both forms of the function are <termref def="dt-deterministic"/>: calling the function twice with the same arguments, within a single
         <termref def="execution-scope">execution scope</termref>, produces the same results.</p><p>The value of the <code nobreak="false">number</code> entry <rfc2119>should</rfc2119> be such that <phrase diff="del" at="B">all eligible <code nobreak="false">xs:double</code>
            values are equally likely to be chosen</phrase> <phrase diff="add" at="B">the distribution of numbers is uniform: for example, the probability of the
         number being in the range 0.1e0 to 0.2e0 is the same as the probability of its being in the range 0.8e0 to 0.9e0</phrase>.</p><p>The function returned in the <code nobreak="false">permute</code> entry <rfc2119>should</rfc2119> be such that all permutations 
            of the supplied sequence are equally likely to be chosen.</p><p>The map returned by the <function>fn:random-number-generator</function> function <rfc2119>may</rfc2119> contain additional entries beyond
            those specified here, but it <rfc2119>must</rfc2119> match the  
            <phrase diff="chg" at="A">record type defined above</phrase>. The meaning of any additional entries
         is <termref def="implementation-defined">implementation-defined</termref>. To avoid conflict with any future version of this specification, the keys of any
         such entries <rfc2119>should</rfc2119> start with an underscore character.</p></def></gitem><gitem><label>Notes</label><def><note><p>It is not meaningful to ask whether the functions returned in the <code nobreak="false">next</code> and <code nobreak="false">permute</code>
            functions resulting from two separate calls with the same seed are “the same function”, but the functions must be equivalent in the sense
            that calling them produces the same sequence of random numbers.</p><p>The repeatability of the results of function calls in different execution scopes is outside the scope of this
            specification. It is <rfc2119>recommended</rfc2119> that when the same seed is provided explicitly, the same random number sequence
            should be delivered even in different execution scopes; while if no seed is provided, the processor should choose a seed
            that is likely to be different from one execution scope to another. (The same effect can be achieved explicitly by using
         <code nobreak="false">fn:current-dateTime()</code> as a seed.)</p><p>The specification does not place strong conformance requirements on the actual randomness of the result; this is left to 
            the implementation. It is desirable, for example, when generating a sequence
         of random numbers that the sequence should not get into a repeating loop; but the specification does not attempt to dictate this.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">random-number-generator()?permute(1 to 100)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>A random permutation of the integers in the range
               <code nobreak="false">1</code> to <code nobreak="false">100</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">random-number-generator()?permute($seq)[1 to (count($seq) idiv 10)]</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>A 10% sample of the items in an input sequence <code nobreak="false">$seq</code>, chosen at random</p></td></tr><tr><td colspan="2" rowspan="1"><p>The following XQuery code produces a random sequence of 200 <code nobreak="false">xs:double</code>
            values in the range zero to one:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">
declare %public function local:random-sequence($length as xs:integer) as xs:double* {
  local:random-sequence($length, random-number-generator())
};
declare %private function local:random-sequence(
  $length as xs:integer, 
  $record as record(number as xs:double, next as fn(*))
) as xs:double* {
  if ($length != 0) {
    $record?number,
    local:random-sequence($length - 1, $record?next())
  }
};
local:random-sequence(200)
            </eg></td></tr><tr><td colspan="2" rowspan="1"><p>An equivalent result can be achieved with <function>fn:fold-left</function>:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">
tail(fold-left(
  (1 to 200),
  random-number-generator(),
  fn($result) { head($result) ! (?next(), ?number), tail($result) }
))
            </eg></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="string-functions"><head>Processing strings</head><p>This section specifies functions and operators on the <bibref ref="xmlschema-2"/>
                <code nobreak="false">xs:string</code> datatype and the datatypes derived from it.</p><div2 id="string-types"><head>String types</head><p>The operators described in this section are defined on the following types.</p><p role="type-hierarchy-figure">
<ulist role="type-hierarchy type-colors"><item role="primitive special root"><ulist><item role="primitive"><p role="item">
               <phrase>string</phrase>
            </p><ulist><item role="built-in-atomic"><p role="first">
                     <phrase>normalizedString</phrase>
                  </p><ulist><item role="built-in-atomic"><p role="first">
                           <phrase>token</phrase>
                        </p><ulist><item role="built-in-atomic"><p role="first">
                                 <phrase>language</phrase>
                              </p></item><item role="built-in-atomic"><p role="last">
                                 <phrase>NMTOKEN</phrase>
                              </p></item><item role="built-in-atomic"><p role="item">
                                 <phrase>Name</phrase>
                              </p><ulist><item role="built-in-atomic"><p role="first">
                                       <phrase>NCName</phrase>
                                    </p><ulist><item role="built-in-atomic"><p role="first">
                                             <phrase>ENTITY</phrase>
                                          </p></item><item role="built-in-atomic"><p role="item">
                                             <phrase>ID</phrase>
                                          </p></item><item role="built-in-atomic"><p role="last">
                                             <phrase>IDREF</phrase>
                                          </p></item></ulist></item></ulist></item></ulist></item></ulist></item></ulist></item></ulist></item></ulist>

<ulist role="type-hierarchy type-colors"><item><p role="root"><phrase>Supertype</phrase></p><ulist><item><p><phrase>subtype</phrase></p></item></ulist></item></ulist>
<ulist role="type-legend type-colors"><item role="built-in-atomic"><p><phrase>Built-in atomic types</phrase></p></item></ulist>
</p><p>They also apply to user-defined types derived by restriction from the above types. </p></div2><div2 id="func-assemble-disassemble-string"><head>Functions to assemble and disassemble strings</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:codepoints-to-string</code></td><td rowspan="1" colspan="1">Returns an <code nobreak="false">xs:string</code> whose characters have supplied <termref def="codepoint">codepoints</termref>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:string-to-codepoints</code></td><td rowspan="1" colspan="1">Returns the sequence of <termref def="codepoint">codepoints</termref> that constitute an
               <code nobreak="false">xs:string</code> value. </td></tr></tbody></table><div3 id="func-codepoints-to-string"><head>fn:codepoints-to-string</head><changes><change issue="414" PR="546" date="2023-07-25">It is no longer automatically an error if the input
               contains a codepoint that is not valid in XML. Instead, the codepoint
            must be a <termref def="dt-permitted-character"/>. The set of permitted
            characters is <termref def="implementation-defined"/>, but it is
            <rfc2119>recommended</rfc2119> that all Unicode characters should 
               be accepted.</change></changes><glist><gitem><label>Summary</label><def><p>Returns an <code nobreak="false">xs:string</code> whose characters have supplied <termref def="codepoint">codepoints</termref>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="codepoints-to-string" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:integer*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the string made up from the <termref def="character">characters</termref> whose Unicode <termref def="codepoint">codepoints</termref> are
            supplied in <code nobreak="false">$values</code>. This will be the zero-length string if <code nobreak="false">$values</code>
            is the empty sequence. </p></def></gitem><gitem><label>Error Conditions</label><def><p diff="chg" at="2023-06-12">A dynamic error is raised <errorref class="CH" code="0001"/> if any of the codepoints in
               <code nobreak="false">$values</code> is not a
               <termref def="dt-permitted-character">permitted character</termref>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoints-to-string((66, 65, 67, 72))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"BACH"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoints-to-string((2309, 2358, 2378, 2325))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"अशॊक"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoints-to-string(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoints-to-string(0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FOCH0001.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-string-to-codepoints"><head>fn:string-to-codepoints</head><glist><gitem><label>Summary</label><def><p>Returns the sequence of <termref def="codepoint">codepoints</termref> that constitute an
               <code nobreak="false">xs:string</code> value. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="string-to-codepoints" return-type="xs:integer*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence of integers, each integer being the Unicode <termref def="codepoint">codepoint</termref> of the corresponding <termref def="character">character</termref> in <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> is a zero-length string or the empty sequence, the function returns
            the empty sequence.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string-to-codepoints("Thérèse")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">84, 104, 233, 114, 232, 115, 101</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="string-compare"><head>Comparison of strings</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:codepoint-equal</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if two strings are equal, considered codepoint-by-codepoint.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:collation</code></td><td rowspan="1" colspan="1">Constructs a collation URI with requested properties.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:collation-available</code></td><td rowspan="1" colspan="1">Asks whether a collation URI is recognized by the implementation.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:collation-key</code></td><td rowspan="1" colspan="1">Given a string value and a collation, generates an internal value called a collation key, with the property that
            the matching and ordering of collation keys reflects the matching and ordering of strings under the specified collation.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:contains-token</code></td><td rowspan="1" colspan="1">Determines whether or not any of the supplied strings, when 
            tokenized at whitespace boundaries, contains the supplied token,
            under the rules of the supplied collation.</td></tr></tbody></table><div3 id="collations"><head>Collations</head><p><termdef id="dt-collation" term="collation"> A <term>collation</term> 
                  is an algorithm that determines, for any two given strings
                  <var>S1</var> and <var>S2</var>, whether <var>S1</var> is less than,
                  equal to, or greater than <var>S2</var>. In this specification,
                  a collation is identified by an absolute URI.</termdef></p><p>The <bibref ref="charmod"/> observes that
                        different applications may require different comparison and ordering behaviors. 
                        Similarly, different users with different linguistic
                        expectations may require different behaviors. Consequently,
                        the collation must be taken into account when comparing strings.</p><p>Collations can indicate that two different codepoints are to be considered equal
                        for comparison purposes (for example, “v” and “w” are considered equivalent in
                        some Swedish collations). Strings can be compared codepoint-by-codepoint or in a
                        linguistically appropriate manner.</p><note><p>Some sources, for example <bibref ref="UNICODE-TR10"/> use the term <term>collation</term>
                     to refer more generically to a set of sorting rules that can be further parameterized
                     or “tailored”. In this specification the term is always used for a specific algorithm
                     in which all such parameters have defined values.</p></note><p>This specification defines some collation URIs that provide interoperable
               sorting behavior across applications. Other collation URIs are defined only
               partially (leaving some aspects implementation-defined). Implementations may
               define further collation URIs, or may allow users or third parties to define them.</p><p>The <termref def="dt-codepoint-collation">Unicode codepoint collation</termref> is 
                  available in every implementation. This collation sorts based on codepoint values. For further details
                  see <specref ref="codepoint-collation"/>.</p><p>Collations may or may not perform Unicode normalization on strings before comparing them.</p><p>This specification allows a collation
                        name to be provided as an argument to many string functions. Although
                        collations are defined to be URIs, they are supplied as instances of
                        <code nobreak="false">xs:string</code>.</p><p>The XQuery/XPath static context supplies a default collation
               for use when the collation argument is not specified.
               (see <xspecref spec="XP40" ref="static_context"/>). 
					If the default collation is not specified by the
               user or the system, the default collation is the 
               <termref def="dt-codepoint-collation">Unicode codepoint collation</termref>.</p><p>If the collation is specified using a relative URI reference, 
                  it is resolved relative to an <termref def="impl-def">implementation-defined</termref> base URI.</p><note><p>Previous versions of this specification stated that it must
               be resolved against the <xtermref spec="XP40" ref="dt-static-base-uri"/>, but this is not always
               operationally convenient. It is <rfc2119>recommended</rfc2119> that processors should provide
               a means of setting the base URI for resolving collation URIs independently of the 
                  <xtermref spec="XP40" ref="dt-static-base-uri"/>, though for backwards compatibility, 
                  the <xtermref spec="XP40" ref="dt-static-base-uri">Static Base URI</xtermref> or 
                  <xtermref spec="XP40" ref="dt-executable-base-uri">Executable Base URI</xtermref> 
                  should be used as a default.</p></note><p>This specification does not define whether or not the collation URI is
					dereferenced. The collation URI may be an abstract identifier, or it may
					refer to an actual resource describing the collation. If it refers to a
					resource, this specification does not define the nature of that resource.
					One possible candidate is that the resource is a locale description
					expressed using the Locale Data Markup Language: see <bibref ref="UNICODE-TR35"/>.
					</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note><note><p>XML allows elements to specify the <code nobreak="false">xml:lang</code> attribute to
                     indicate the language associated with the content of such an element.
                     This specification does not use <code nobreak="false">xml:lang</code> to identify the
                     default collation because using
                     <code nobreak="false">xml:lang</code> does not produce desired effects when the two
                     strings to be compared have different <code nobreak="false">xml:lang</code> values or
                     when a string is multilingual. </p></note></div3><div3 id="collation-capabilities"><head>Collation Capabilities</head><p>All collations support the ability to compare two strings to decide
               whether they are equal, and if not, which one should sort first. This
               must always define a total ordering, which implies that the comparison
               is transitive.</p><p>A collation may (or may not) support the ability to derive a <term>collation key</term>
                  for a given string. A collation key is a binary value obtained as a function
                  of a string <var>S</var> and a collation <var>C</var>, 
                  such that the collation keys for two strings <var>S1</var> and <var>S2</var>
                  have the same ordering relationship (less than, equal, or greater than) as
                  the two strings themselves, when compared under the relevant collation.
                  Collation keys are useful for operations such as indexing, because they
                  can be used as keys in maps. They are available using the 
                  <function>fn:collation-key</function> function.</p><p>Furthermore, a collation may (or may not) support the ability to determine whether
               one string is a substring of another under that collation. The use of collations
               in substring matching is described in <specref ref="substring.functions"/>.</p><p>The capabilities of a collation may be determined using the 
               <function>fn:collation-available</function> function.</p></div3><div3 id="codepoint-collation"><head>The Unicode Codepoint Collation</head><p><termdef id="dt-codepoint-collation" term="Unicode codepoint collation">The collation URI
                  <code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code> identifies
               a collation which must be recognized by every implementation: it is referred to as
               the <term>Unicode codepoint collation</term> (not to be confused with the Unicode collation algorithm).</termdef></p><p>The Unicode codepoint collation does not perform any normalization on the
               supplied strings.</p><p>The collation is defined as follows. Each of the two strings is
               converted to a sequence of integers using the <function>fn:string-to-codepoints</function>
               function. These two sequences <code nobreak="false">$A</code> and <code nobreak="false">$B</code> are then compared as follows: </p><olist><item><p>If both sequences are empty, the strings are equal.</p></item><item><p>If one sequence is empty and the other is not, then the string
                     corresponding to the empty sequence is less than the other string.</p></item><item><p>If the first integer in <code nobreak="false">$A</code> is less than the first integer in <code nobreak="false">$B</code>, then
                     the string corresponding to <code nobreak="false">$A</code> is less than the string corresponding to
                     <code nobreak="false">$B</code>.
                  </p></item><item><p>If the first integer in <code nobreak="false">$A</code> is greater than the first integer in <code nobreak="false">$B</code>, then
                     the string corresponding to <code nobreak="false">$A</code> is greater than the string corresponding to
                     <code nobreak="false">$B</code>.</p></item><item><p>Otherwise (the first pair of integers are equal), the result is obtained
                    by applying the same rules recursively to <code nobreak="false">fn:tail($A)</code> and
                    <code nobreak="false">fn:tail($B)</code></p></item></olist><note><p>While the Unicode codepoint collation does not produce results suitable for quality publishing of
               printed indexes or directories, it is adequate for many purposes where a restricted alphabet
               is used, such as sorting of vehicle registrations.</p></note><note><p>The Unicode codepoint collation differs from the
               default sort order used in programming languages that sort strings
               based on UTF-16 code units, which may include surrogate pairs.</p></note></div3><div3 id="uca-collations"><head>The Unicode Collation Algorithm</head><p>This specification defines a family of collation URIs representing tailorings of the Unicode Collation
                  Algorithm (UCA) as defined in <bibref ref="UNICODE-TR10"/>. The parameters used for tailoring the UCA
                  are based on the parameters defined in the Locale Data Markup Language (LDML), defined in <bibref ref="UNICODE-TR35"/>.</p><p>This family of URIs use the scheme and path <code nobreak="false">http://www.w3.org/2013/collation/UCA</code>
                  followed by an optional query part. The query part, if present, consists of a question mark followed
                  by a sequence of zero or more semicolon-separated parameters. Each parameter is a keyword-value pair, the
                  keyword and value being separated by an equals sign.</p><p>All implementations must recognize URIs in this family in the <code nobreak="false">collation</code> argument of functions that
                  take a collation argument.</p><p>If the <code nobreak="false">fallback</code> parameter is
                  present with the value <code nobreak="false">no</code>, then the implementation <rfc2119>must</rfc2119> either use a collation that conforms with
                  the rules in the Unicode specifications for the requested tailoring, or fail with a static or dynamic error indicating that it
                  does not provide the collation (the error code should be the same as if the collation URI were not recognized). 
                  If the <code nobreak="false">fallback</code> parameter
                  is omitted or takes the value <code nobreak="false">yes</code>, and if the collation URI is well-formed according to the rules in this section,
                  then the implementation <rfc2119>must</rfc2119> accept the collation URI, and <rfc2119>should</rfc2119> use the available
                  collation that most closely reflects the user’s intentions. For example, if the collation URI requested is
                  <code nobreak="false">http://www.w3.org/2013/collation/UCA?lang=se;fallback=yes</code> and the implementation does not include a fully
                  conformant version of the UCA tailored for Swedish, then it <rfc2119>may</rfc2119> choose to use a Swedish collation that is known to differ
                  from the UCA definition, or one whose conformance has not been established. It might even, as a last resort, fall back to using
                  codepoint collation.</p><p>If two query parameters use the same keyword then the last one wins. If a query parameter uses a keyword or value which is not
                  defined in this specification then the meaning is <termref def="implementation-defined"/>. If the implementation recognizes
                  the meaning of the keyword and value then it <rfc2119>should</rfc2119> interpret it accordingly; if it does not recognize
                  the keyword or value then if the <code nobreak="false">fallback</code> parameter is present with the value <code nobreak="false">no</code> it should reject
                  the collation as unsupported, otherwise it should ignore the unrecognized parameter.</p><p>The following query parameters are defined. If any parameter is absent, the default is <termref def="implementation-defined"/>
                  except where otherwise stated.
                  The meaning given for each parameter is non-normative; the normative specification is found in <bibref ref="UNICODE-TR35"/>.</p><table role="longlastcol data"><thead><tr><th rowspan="1" colspan="1">Keyword</th><th rowspan="1" colspan="1">Values</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">fallback</td><td rowspan="1" colspan="1">yes | no (default yes)</td><td rowspan="1" colspan="1">Determines whether the processor uses a fallback collation if a conformant collation is not available.</td></tr><tr><td rowspan="1" colspan="1">lang</td><td rowspan="1" colspan="1">language code: a string in the lexical space of <code nobreak="false">xs:language</code>.</td><td rowspan="1" colspan="1">The language whose collation conventions are to be used.</td></tr><tr><td rowspan="1" colspan="1">version</td><td rowspan="1" colspan="1">string</td><td rowspan="1" colspan="1">The version number of the UCA to be used.</td></tr><tr><td rowspan="1" colspan="1">strength</td><td rowspan="1" colspan="1">primary | secondary | tertiary | quaternary | identical, or 
                        1|2|3|4|5 as synonyms (default tertiary / 3)</td><td rowspan="1" colspan="1">The collation strength as defined in UCA. Primary 
                           strength takes only the base form of the character into account (so A=a=Ä=ä); secondary strength ignores case but considers accents
                           and diacritics as significant (so A=a and Ä=ä but ä≠a); tertiary considers case as significant (A≠a≠Ä≠ä); quaternary strength always considers as significant spaces and punctuation 
                           (data-base≠database; if <code nobreak="false">maxVariable</code> is <code nobreak="false">punct</code> or higher and 
                           <code nobreak="false">alternate</code> is not <code nobreak="false">non-ignorable</code>, lower strengths will treat data-base=database).</td></tr><tr><td rowspan="1" colspan="1">maxVariable</td><td rowspan="1" colspan="1">space | punct | symbol | currency (default punct)</td><td rowspan="1" colspan="1">
                        Given the sequence <code nobreak="false">space</code>, <code nobreak="false">punct</code>, <code nobreak="false">symbol</code>, <code nobreak="false">currency</code>, 
                        all characters in the specified group and earlier groups are treated as “noise” characters 
                        to be handled as defined by the <code nobreak="false">alternate</code> parameter. For example, <code nobreak="false">maxVariable=punct</code> indicates 
                        that characters classified as whitespace or punctuation get this treatment.</td></tr><tr><td rowspan="1" colspan="1">alternate</td><td rowspan="1" colspan="1">non-ignorable | shifted | blanked (default non-ignorable)</td><td rowspan="1" colspan="1">Controls the handling of characters such as spaces and hyphens;
                     specifically, the "noise" characters in the groups selected by the <code nobreak="false">maxVariable</code> parameter. The value <code nobreak="false">non-ignorable</code>
                     indicates that such characters are treated as distinct at the primary level (so <code nobreak="false">data base</code> sorts before <code nobreak="false">database</code>);
                     <code nobreak="false">shifted</code> indicates that they are used to differentiate two strings only at the <code nobreak="false">quaternary</code> level,
                     and <code nobreak="false">blanked</code> indicates that they are taken into account only at the <code nobreak="false">identical</code> level.</td></tr><tr><td rowspan="1" colspan="1">backwards</td><td rowspan="1" colspan="1">yes | no (default no)</td><td rowspan="1" colspan="1">The value <code nobreak="false">backwards=yes</code> indicates that the last accent in the 
                           string is the most significant.</td></tr><tr><td rowspan="1" colspan="1">normalization</td><td rowspan="1" colspan="1">yes | no (default no)</td><td rowspan="1" colspan="1">Indicates whether strings 
                           are converted to normalization form D.</td></tr><tr><td rowspan="1" colspan="1">caseLevel</td><td rowspan="1" colspan="1">yes | no (default no)</td><td rowspan="1" colspan="1">When used with primary strength, setting <code nobreak="false">caseLevel=yes</code> has the effect of ignoring accents
                        while taking account of case.</td></tr><tr><td rowspan="1" colspan="1">caseFirst</td><td rowspan="1" colspan="1">upper | lower (default lower)</td><td rowspan="1" colspan="1">Indicates whether upper-case precedes lower-case or vice versa.</td></tr><tr><td rowspan="1" colspan="1">numeric</td><td rowspan="1" colspan="1">yes | no (default no)</td><td rowspan="1" colspan="1">When <code nobreak="false">numeric=yes</code> is specified, a sequence of consecutive digits is interpreted as a number,
                        for example <code nobreak="false">chap2</code> sorts before <code nobreak="false">chap12</code>.</td></tr><tr><td rowspan="1" colspan="1">reorder</td><td rowspan="1" colspan="1">a comma-separated sequence of reorder codes, where a reorder code is one of <code nobreak="false">space</code>, <code nobreak="false">punct</code>,
                        <code nobreak="false">symbol</code>, <code nobreak="false">currency</code>, <code nobreak="false">digit</code>, or a four-letter script code defined in <bibref ref="ISO15924_register"/>, the register
                        of scripts maintained by the Unicode Consortium in its capacity as registration authority for <bibref ref="ISO15924"/>.</td><td rowspan="1" colspan="1">Determines the relative ordering of text in different scripts; for example the value <code nobreak="false">digit,Grek,Latn</code> indicates
                           that digits precede Greek letters, which precede Latin letters.</td></tr></tbody></table><note><p>This list excludes parameters that are inconvenient to express in a URI, 
                  or that are applicable only to substring matching.</p></note><p>UCA collation URIs can be conveniently generated using the
                  <function>fn:collation</function> function.</p></div3><div3 id="unicode-case-insensitive-collation"><head>The Unicode case-insensitive collation</head><changes><change issue="1568">
                     A new collation URI is defined for Unicode case-insensitive comparison and ordering.
                  </change></changes><p>The collation URI <code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/unicode-case-insensitive</code> must be recognized
                  by every implementation.</p><p>The collation is defined as follows:</p><ulist><item><p>Let <code nobreak="false">$UCI</code> be the collation URI 
                     <code nobreak="false">"http://www.w3.org/2005/xpath-functions/collation/unicode-case-insensitive"</code>.</p></item><item><p>Let <code nobreak="false">$UCC</code> be the Unicode Codepoint Collation URI
                     <code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>.</p></item><item><p>For any two strings <code nobreak="false">$A</code> and <code nobreak="false">$B</code>, the result
                     of the comparison <code nobreak="false">fn:compare($A, $B, $UCI)</code> is defined to be the same as
                  the result of <code nobreak="false">fn:compare(lower-case($A), lower-case($B), $UCC)</code>.</p></item></ulist><p>The collation supports collation units and can therefore
               be used with functions such as <function>fn:contains</function>; 
                  each Unicode codepoint is a single collation unit. The collation
               also supports the ability to obtain a collation key using 
               <function>fn:collation-key</function>.</p></div3><div3 id="html-ascii-case-insensitive-collation" diff="chg" at="issue668"><head>The HTML ASCII Case-Insensitive Collation</head><changes><change issue="668" PR="680" date="2023-09-05">
                     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.
                  </change></changes><p>The collation URI <code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive</code> must be recognized
                  by every implementation. It is <phrase diff="chg" at="issue668">designed to be compatible with</phrase> 
               the HTML ASCII case-insensitive collation as defined in <bibref ref="html5"/> (section 4.6, <emph>Strings</emph>), 
                  which is used, for example, when matching HTML <code nobreak="false">class</code> attribute values.</p><p>The collation is defined as follows:</p><ulist><item><p>Let <code nobreak="false">$HACI</code> be the collation URI 
                     <code nobreak="false">"http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"</code>.</p></item><item><p>Let <code nobreak="false">$UCC</code> be the Unicode Codepoint Collation URI
                     <code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>.</p></item><item><p>Let <code nobreak="false">$lc</code> be the function <code nobreak="false">
                  fn:translate(?, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")</code>.</p></item><item><p>Then for any two strings <code nobreak="false">$A</code> and <code nobreak="false">$B</code>, the result
                     of the comparison <code nobreak="false">fn:compare($A, $B, $HACI)</code> is defined to be the same as
                  the result of <code nobreak="false">fn:compare($lc($A), $lc($B), $UCC)</code>.</p></item></ulist><note><p>HTML5 defines the semantics of equality matching using this collation; <phrase diff="add" at="issue668">this
                  specification additionally defines ordering rules. </phrase>
                  The collation supports collation units and can therefore
               be used with functions such as <function>fn:contains</function>; each Unicode codepoint is a single collation unit.</p><p>The corresponding HTML5 definition is: A string <var>A</var> is an ASCII case-insensitive match 
                     for a string <var>B</var>, if the ASCII lowercase of <var>A</var> is the ASCII lowercase of <var>B</var>.</p></note></div3><div3 id="choosing-a-collation"><head>Choosing a collation</head><p diff="chg" at="2023-07-04">Many functions have a signature that includes a <code nobreak="false">$collation</code>
			   argument, which is generally optional and takes <code nobreak="false">default-collation()</code>
			      as its default value.</p><p>The collation to use for these functions is determined by the following rules:</p><olist><item><p>If the function specifies an explicit collation, CollationA (e.g., if
                                the optional collation argument is specified in a call of the
                                <function>fn:compare</function> function), then:</p><ulist><item><p>If CollationA is supported by the implementation, then
                                        CollationA is used. </p></item><item><p>Otherwise, a dynamic error is raised <errorref class="CH" code="0002"/>. </p></item></ulist></item><item><p>If no collation is explicitly specified for the function 
                        <phrase diff="add" at="2023-07-04">(that is,
                        if the <code nobreak="false">$collation</code> argument is omitted or is set to an
                        empty sequence)</phrase>, and the
                        default collation in the XQuery/XPath static context is CollationB, then:</p><ulist><item><p>If CollationB is supported by the implementation, then
                                        CollationB is used. </p></item><item><p>Otherwise, a dynamic error is raised <errorref class="CH" code="0002"/>. </p></item></ulist></item></olist><note><p>Because the set of collations that are supported is <termref def="implementation-defined">implementation-defined</termref>,
			   an implementation has the option to support all collation URIs, in which case it will never raise this error.</p></note><p>If the value of the collation argument is a relative URI reference, it is resolved against the base-URI from the
			      static context. If it is a relative URI reference and cannot be resolved, perhaps because the base-URI property in the static context
			      is absent, a dynamic error is raised <errorref class="CH" code="0002"/>.</p><note><p>There is no explicit requirement that the string used as a collation URI be a valid URI.
			   Implementations will in many cases reject such strings on the grounds that do not identify a supported collation; they
			   may also cause an error if they cannot be resolved against the <phrase diff="chg" at="2023-05-19">relevant</phrase> base URI.</p></note></div3><div3 id="func-codepoint-equal"><head>fn:codepoint-equal</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if two strings are equal, considered codepoint-by-codepoint.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="codepoint-equal" return-type="xs:boolean?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value1" type="xs:string?"/><arg name="value2" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If either argument is the empty sequence, the function returns the empty sequence. </p><p>Otherwise, the function returns <code nobreak="false">true</code> or <code nobreak="false">false</code> depending on
            whether <code nobreak="false">$value1</code> is equal to 
            <code nobreak="false">$value2</code>, according to the Unicode codepoint collation
               (<code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></def></gitem><gitem><label>Notes</label><def><note><p>This function allows <code nobreak="false">xs:anyURI</code> values to be compared without having to
            specify the Unicode codepoint collation.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoint-equal("abcd", "abcd")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoint-equal("abcd", "abcd ")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoint-equal("", "")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoint-equal("", ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">codepoint-equal((), ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-collation"><head>fn:collation</head><changes><change issue="1091" PR="1093" date="2024-04-09">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Constructs a collation URI with requested properties.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="collation" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="options" type="map(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>The function is supplied with a map defining the properties required of 
            the collation, and returns a collation URI with these properties.</p><p>Specifically, it returns a string in the form of a URI with the scheme and path
               <code nobreak="false">http://www.w3.org/2013/collation/UCA</code> followed by an optional 
               query part. The query part is absent if <code nobreak="false">options</code> is empty.
               Otherwise it consists of a question mark followed 
               by a sequence of one or more semicolon-separated parameters. Each parameter 
               is a keyword-value pair, the keyword and value being separated by an equals sign.
               There is one keyword-value pair for each entry in the <code nobreak="false">options</code> map: 
               the keyword is the same as the string value of the key in the map, and the value
               is the string value of the corresponding value, except where the value is of
               type <code nobreak="false">xs:boolean</code>, in which case <code nobreak="false">true</code> and <code nobreak="false">false</code>
               are translated to <code nobreak="false">yes</code> and <code nobreak="false">no</code>.
            </p><p>The function does not check whether the implementation actually recognizes
         the resulting collation URI: that can be achieved using the <function>fn:collation-available</function>
         function.</p><p>The properties available are as defined for the Unicode Collation Algorithm 
            (see <specref ref="uca-collations"/>). Additional <termref def="implementation-defined"/>
            properties <rfc2119>may</rfc2119> be specified  as described in the rules for UCA 
            collation URIs.</p><p>The <termref def="option-parameter-conventions">option parameter conventions</termref> 
            apply, except as regards the handling of options not defined in this specification.
            Specifically:</p><ulist><item><p>If the option key is of type <code nobreak="false">xs:string</code>, <code nobreak="false">xs:anyURI</code>,
            or <code nobreak="false">xs:untypedAtomic</code> then it is converted to a string, and produces
               a URI query parameter which is handled as described in  <specref ref="uca-collations"/>.
            </p></item><item><p>If the option key is of any other type then the function fails with a
               type error <xerrorref spec="XP" class="TY" code="0004"/>.</p></item></ulist><p>The following options are defined:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="fallback" type="xs:boolean" occur="opt"/><arg name="lang" type="xs:language" occur="opt"/><arg name="version" type="xs:string" occur="opt"/><arg name="strength" type="enum(&#34;primary&#34;, &#34;secondary&#34;, &#34;tertiary&#34;,&#xA;               &#34;quaternary&#34;, &#34;identical&#34;, &#34;1&#34;, &#34;2&#34;, &#34;3&#34;, &#34;4&#34;, &#34;5&#34;)" occur="opt"/><arg name="maxVariable" type="enum(&#34;space&#34;, &#34;punct&#34;, &#34;symbol&#34;,&#xA;                  &#34;currency&#34;)" occur="opt"/><arg name="alternate" type="enum(&#34;non-ignorable&#34;, &#34;shifted&#34;, &#34;blanked&#34;,&#xA;                  &#34;currency&#34;)" occur="opt"/><arg name="backwards" type="xs:boolean" occur="opt"/><arg name="normalization" type="xs:boolean" occur="opt"/><arg name="caseLevel" type="xs:boolean" occur="opt"/><arg name="caseFirst" type="enum(&#34;upper&#34;,&#34;lower&#34;)" occur="opt"/><arg name="numeric" type="xs:boolean" occur="opt"/><arg name="reorder" type="xs:string" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">fallback?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">lang?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:language</code></p></item><item><p><term>Default: </term><code nobreak="false">default-language()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">version?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">strength?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">enum("primary", "secondary", "tertiary",
               "quaternary", "identical", "1", "2", "3", "4", "5")</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">maxVariable?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">enum("space", "punct", "symbol",
                  "currency")</code></p></item><item><p><term>Default: </term><code nobreak="false">"punct"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">alternate?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">enum("non-ignorable", "shifted", "blanked",
                  "currency")</code></p></item><item><p><term>Default: </term><code nobreak="false">"non-ignorable"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">backwards?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">normalization?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">caseLevel?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">caseFirst?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">enum("upper","lower")</code></p></item><item><p><term>Default: </term><code nobreak="false">"lower"</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">numeric?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">reorder?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">See <specref ref="uca-collations"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">""</code></p></item></ulist></td></tr></tbody></table></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <xerrorref spec="XP" class="TY" code="0004"/> if 
            <code nobreak="false">options</code> includes an entry whose key is not of
            type <code nobreak="false">xs:string</code>, <code nobreak="false">xs:anyURI</code>,
            or <code nobreak="false">xs:untypedAtomic</code>, or whose corresponding value
            is not castable to <code nobreak="false">xs:string</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">collation({})</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://www.w3.org/2013/collation/UCA"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">collation({ 'lang': 'de' })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://www.w3.org/2013/collation/UCA?lang=de"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">collation({ 'lang': 'de', 'strength': 'primary' })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://www.w3.org/2013/collation/UCA?lang=de;strength=primary"</code></p><p><emph>(The order of query parameters may vary.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">collation({ 'lang': default-language() })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>A collation suitable for the default language in the
               dynamic context.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-collation-available"><head>fn:collation-available</head><changes><change issue="1160" PR="1262" date="2024-07-09">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Asks whether a collation URI is recognized by the implementation.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="collation-available" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="collation" type="xs:string"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>The supplied argument is a candidate collation URI.</p><p>The function returns true if and only if the implementation recognizes the candidate
            collation URI.</p></def></gitem><gitem><label>Notes</label><def><note><p>If the candidate collation is a UCA collation specifying <code nobreak="false">fallback=yes</code>,
         then this function will always return true: implementations are required to recognize
         such a collation and use fallback behavior if there is no direct equivalent available.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">collation-available("http://www.w3.org/2013/collation/UCA?lang=de")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">collation({ 'lang': 'de' }) =&gt; collation-available()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-collation-key"><head>fn:collation-key</head><glist><gitem><label>Summary</label><def><p>Given a string value and a collation, generates an internal value called a collation key, with the property that
            the matching and ordering of collation keys reflects the matching and ordering of strings under the specified collation.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="collation-key" return-type="xs:base64Binary" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>Calling the one-argument version of this function is equivalent to calling the
            two-argument version supplying the default collation as the second argument.</p><p>The function returns an <termref def="implementation-dependent">implementation-dependent</termref> 
            value with the property that,
            for any two strings <code nobreak="false">$K1</code> and <code nobreak="false">$K2</code>:</p><ulist><item><p><code nobreak="false">collation-key($K1, $C) eq collation-key($K2, $C)</code> if and only if
                  <code nobreak="false">compare($K1, $K2, $C) eq 0</code></p></item><item><p><code nobreak="false">collation-key($K1, $C) lt collation-key($K2, $C)</code> if and only if
                  <code nobreak="false">compare($K1, $K2, $C) lt 0</code></p></item></ulist><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. Collation keys are defined as <code nobreak="false">xs:base64Binary</code> values
            to ensure unambiguous and context-free comparison semantics.</p><p>An implementation is free to generate a collation key in any convenient way provided
            that it always generates the same collation key for two strings that are equal under the
            collation, and different collation keys for strings that are not equal. This holds only
            within a single <termref def="execution-scope">execution scope</termref>;
            an implementation is under no obligation to generate the same collation keys during a
            subsequent unrelated query or transformation.</p><p>It is possible to define collations that do not have the ability to generate collation
            keys. Supplying such a collation will cause the function to fail. The ability to
            generate collation keys is an <termref def="implementation-defined">implementation-defined</termref> property of the
            collation.</p></def></gitem><gitem><label>Error Conditions</label><def><p>An error is raised <errorref class="CH" code="0004"/> if the specified
            collation does not support the generation of collation keys. </p></def></gitem><gitem><label>Notes</label><def><note><p>The function is provided primarily for use with maps. If a map is required where
            codepoint equality is inappropriate for comparing keys, then a common technique is to
            normalize the key so that equality matching becomes feasible. There are many ways
            keys can be normalized, for example by use of functions such as
               <function>fn:upper-case</function>, <function>fn:lower-case</function>,
               <function>fn:normalize-space</function>, or <function>fn:normalize-unicode</function>, but this
            function provides a way of normalizing them according to the rules of a specified
            collation. For example, if the collation ignores accents, then the function will
            generate the same collation key for two input strings that differ only in their use of
            accents.</p><p>The result of the function is defined to be an <code nobreak="false">xs:base64Binary</code> value. Binary values
         are chosen because they have unambiguous and context-free comparison semantics, because the value space
         is unbounded, and because the ordering rules are such that between any two values in the ordered value space, an
         arbitrary number of further values can be interpolated. The choice between <code nobreak="false">xs:base64Binary</code>
            and <code nobreak="false">xs:hexBinary</code> is arbitrary; the only operation that behaves differently between the two binary
            data types is conversion to/from a string, and this operation is not one that is normally required for
            effective use of collation keys.
         </p><p>For collations based on the Unicode Collation Algorithm, an algorithm for computing
            collation keys is provided in <bibref ref="UNICODE-TR10"/>. Implementations are
               <rfc2119>not required</rfc2119> to use this algorithm.</p><p>The fact that collation keys are ordered can be exploited in XQuery, whose <code nobreak="false">order by</code>
         clause does not allow the collation to be selected dynamically. This restriction can be circumvented
         by rewriting the clause <code nobreak="false">order by $e/@key collation "URI"</code> as <code nobreak="false">order by fn:collation-key($e/@key, $collation)</code>,
         where <code nobreak="false">$collation</code> allows the collation to be chosen dynamically.</p><p>Note that <code nobreak="false">xs:base64Binary</code> becomes an ordered type
         in XPath 3.1, making binary collation keys possible.</p><p>The <function>fn:collation-available</function> can be used to ask whether a particular
         collation is capable of delivering collation keys.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $C := collation({ 'strength': 'primary' })</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge(
  ({ collation-key("A", $C): 1 }, { collation-key("a", $C): 2 }),
  { "duplicates": "use-last" }
)(collation-key("A", $C))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2</eg><p><emph>(Given that the keys of the two entries are equal under the rules of
                  the chosen collation, only one of the entries can appear in the result; the one
                  that is chosen is the one from the last map in the input sequence.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $M := {
  collation-key("A", $C): 1,
  collation-key("B", $C): 2
}
return $M(collation-key("a", $C))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(The strings <code nobreak="false">"A"</code> and <code nobreak="false">"a"</code> have the same collation key under this
                  collation.)</emph></p></td></tr><tr><td colspan="2" rowspan="1"><p>As the above examples illustrate, it is important that when the
                  <code nobreak="false">collation-key</code> function is used to add entries to a map, then it must
               also be used when retrieving entries from the map. This process can be made less
               error-prone by encapsulating the map within a function:
               <code nobreak="false">fn($k) { $M(collation-key($k, $collation) }</code>.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-contains-token"><head>fn:contains-token</head><glist><gitem><label>Summary</label><def><p>Determines whether or not any of the supplied strings, when 
            tokenized at whitespace boundaries, contains the supplied token,
            under the rules of the supplied collation.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="contains-token" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string*"/><arg name="token" type="xs:string"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns <code nobreak="false">false</code>.</p><p>Leading and trailing whitespace is trimmed from <code nobreak="false">$token</code>. 
            If the trimmed value of <code nobreak="false">$token</code>
            is a zero-length string, the function returns <code nobreak="false">false</code>.</p><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>The function returns <code nobreak="false">true</code> if and only if there is string in <code nobreak="false">$value</code> which, 
            after tokenizing at whitespace boundaries, contains a token
         that is equal to the trimmed value of <code nobreak="false">$token</code> under
         the rules of the selected collation.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">some $t in ($value ! tokenize(.))
satisfies compare($t, replace($token, '^\s*|\s*$', ''), $collation) eq 0</eg></def></gitem><gitem><label>Notes</label><def><note><p>Interior whitespace within <code nobreak="false">$token</code> will cause the function to return <code nobreak="false">false</code>,
         unless such whitespace is ignored by the selected collation.</p><p>This function can be used for processing space-separated attribute values
            (for example, the XHTML and DITA class attribute),
            where one often needs to test for the presence
            of a single token in a space-separated list. The function is designed to work
            both when the attribute has been validated against an XSD list type, and when it
            appears as a single untyped string. It differs from the
            HTML 5 definition in that HTML 5 recognizes form feed (x0C) as a separator.
            To reproduce the HTML token matching behavior, the HTML ASCII case-insensitive collation
            should be used: see <specref ref="html-ascii-case-insensitive-collation"/>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-token("red green blue ", "red")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-token(("red", "green", "blue"), " red ")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">contains-token("red, green, blue", "red")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains-token(
  "red green blue",
  "RED",
  "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="string-value-functions"><head>Functions on string values</head><p>The following functions are defined on values of type <code nobreak="false">xs:string</code> and
                    types derived from it.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:char</code></td><td rowspan="1" colspan="1">Returns a string containing a particular character or glyph.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:characters</code></td><td rowspan="1" colspan="1">Splits the supplied string into a sequence of single-character strings.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:graphemes</code></td><td rowspan="1" colspan="1">Splits the supplied string into a sequence of single-grapheme strings.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:concat</code></td><td rowspan="1" colspan="1">Returns the concatenation of the arguments, treated as sequences of strings.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:string-join</code></td><td rowspan="1" colspan="1">Returns a string created by concatenating the items in a sequence, with a defined
            separator between adjacent items.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:substring</code></td><td rowspan="1" colspan="1">Returns the part of <code nobreak="false">$value</code> beginning at the position
            indicated by <code nobreak="false">$start</code> and continuing for the number of <termref def="character">characters</termref> indicated by <code nobreak="false">$length</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:string-length</code></td><td rowspan="1" colspan="1">Returns the number of <termref def="character">characters</termref> in a string.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:normalize-space</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">$value</code> with leading and trailing whitespace removed, and
            sequences of internal whitespace reduced to a single space character.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:normalize-unicode</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">$value</code> after applying Unicode normalization.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:upper-case</code></td><td rowspan="1" colspan="1">Converts a string to upper case.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:lower-case</code></td><td rowspan="1" colspan="1">Converts a string to lower case.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:translate</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">$value</code> modified by replacing or removing individual
            characters. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:hash</code></td><td rowspan="1" colspan="1">Returns the results of a specified hash, checksum, or
            cyclic redundancy check function applied to the input.</td></tr></tbody></table><notes><p>When the above operators and functions are applied to datatypes derived from
                        <code nobreak="false">xs:string</code>, they are guaranteed to return values that are instances of
                        <code nobreak="false">xs:string</code>, but the value might or might not be an instance of the
                        particular subtype of <code nobreak="false">xs:string</code> to which they were applied. </p><p>The strings returned by <function>fn:concat</function> and <function>fn:string-join</function> are not guaranteed to be normalized.  
			   But see note in <function>fn:concat</function>.
                </p></notes><div3 id="func-char" diff="add" at="2022-11-19"><head>fn:char</head><changes><change issue="121 989" PR="261 306 993" date="2023-01-10">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a string containing a particular character or glyph.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="char" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:string | xs:positiveInteger)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a string, generally containing a single <termref def="character">character</termref> or glyph, identified by <code nobreak="false">$value</code>.</p><p>The supplied value of <code nobreak="false">$value</code> must be one of the following:</p><olist><item><p>A Unicode codepoint, supplied as an integer. For example <code nobreak="false">fn:char(9)</code>
            returns the tab character.</p></item><item><p>An HTML5 character reference name (often referred to as an entity name) as defined
               at <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://html.spec.whatwg.org/multipage/named-characters.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://html.spec.whatwg.org/multipage/named-characters.html</loc>. The name is
               written with no leading ampersand and no trailing semicolon.
               For example <code nobreak="false">fn:char("pi")</code> represents the character
               <char>U+03C0</char> and <code nobreak="false">fn:char("nbsp")</code> returns 
               <char>U+00A0</char>.</p><p>A processor <rfc2119>may</rfc2119> recognize additional character reference names defined in
                  other versions of HTML. Character reference names are case-sensitive.</p><p>In the event that the HTML5 character reference name identifies a string
               comprising multiple codepoints, that string is returned.</p><p>[TODO: add a proper bibliographic reference.]</p></item><item><p>A backslash-escape sequence from the set <code nobreak="false">\n</code> (<char>U+000A</char>), 
               <code nobreak="false">\r</code> (<char>U+000D</char>),
               or <code nobreak="false">\t</code> (<char>U+0009</char>).</p></item></olist><p diff="chg" at="2023-06-12">The result must consist of
         <termref def="dt-permitted-character">permitted characters</termref>.
         For example <code nobreak="false">fn:char(0xDEAD)</code> is invalid because it is in the surrogate range.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The function fails with a dynamic error <errorref class="CH" code="0005"/> if <code nobreak="false">$value</code> is not a valid
            representation of a <termref def="dt-permitted-character"/> 
            or sequence of permitted characters.
         </p></def></gitem><gitem><label>Notes</label><def><note><p>Although all Unicode characters can appear in string literals (the delimiting quotation marks can be
         escaped by doubling them), some characters are not visually distinctive, so representing them by name
         may make code more readable. In addition, there may be contexts where it is necessary or prudent to
         write XPath expressions using ASCII characters only, for example where an expression is used in the query
         part of a URI.</p><p>A few HTML5 character reference names identify glyphs whose Unicode
         representation uses multiple codepoints. For example, the name
            <code nobreak="false">NotEqualTilde</code> refers to the glyph <code nobreak="false">≂̸</code> which is expressed
            using the two codepoints <char>U+2242</char>, <char>U+0338</char>. In such cases the string length of
         the result of the function will exceed one.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">char("aacute")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"á"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">char("eth")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"ð"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">char(9)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">codepoints-to-string(9)</code></p><p><emph>(The character <emph>tab</emph>).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">char("\t")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">codepoints-to-string(9)</code></p><p><emph>(The character <emph>tab</emph>).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">char(0x20)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">" "</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">char(0x1D1CA)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"𝇊"</code></p><p><emph>(The character MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">char("NotEqualTilde")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">codepoints-to-string((8770, 824))</code></p><p><emph>(This HTML5 character reference name expands to multiple codepoints.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-characters" diff="add" at="A"><head>fn:characters</head><changes><change date="2022-09-20">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Splits the supplied string into a sequence of single-character strings.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="characters" return-type="xs:string*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence of strings, each string having length 1, containing
            the corresponding <termref def="character">character</termref> in <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> is a zero-length string or the empty sequence, the function returns
            the empty sequence.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">string-to-codepoints($value) ! codepoints-to-string(.)</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">characters("Thérèse")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"T", "h", "é", "r", "è", "s", "e"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">characters("")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">characters(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">characters("Banana") =&gt; index-of("a")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2, 4, 6</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">characters("stretch") =&gt; string-join("-")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"s-t-r-e-t-c-h"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Banana"
=&gt; characters()
=&gt; reverse()
=&gt; string-join()</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"ananaB"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-graphemes" diff="add" at="A"><head>fn:graphemes</head><changes><change issue="73" PR="1068" date="2024-05-15">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Splits the supplied string into a sequence of single-grapheme strings.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="graphemes" return-type="xs:string*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence of strings. Each string in the sequence contains one or
            more <termref def="character">character</termref>s that collectively constitute a single
            extended grapheme cluster, as defined by <bibref ref="UNICODE-TR29"/>.</p><p>If <code nobreak="false">$value</code> is a zero-length string or the empty sequence, the function returns
            the empty sequence.</p></def></gitem><gitem><label>Notes</label><def><note><p>The resultant sequence of strings are extended graphemes, not legacy graphemes (see 
            <bibref ref="UNICODE-TR29"/>).</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">graphemes("a" || char(0x308) || "b")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a" || char(0x308), "b"</code></p><p><emph>(a + ◌̈ + b, three characters, two graphemes).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">graphemes("")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">graphemes(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">graphemes(char('\r') || char('\n'))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">char('\r') || char('\n')</code></p><p><emph>(Carriage return + line feed, two characters, one
                  grapheme).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">graphemes(char(0x1F476) || char(0x200D) || char(0x1F6D1))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">char(0x1F476) || char(0x200D) || char(0x1F6D1)</code></p><p><emph>(👶 +ZWJ + 🛑, three characters, one grapheme).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">graphemes("कत")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"क", "त"</code></p><p><emph>(क + त, two characters, two graphemes).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">graphemes("क" || char(0x93C) || char(0x200D) || char(0x94D) || "त")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"क" || char(0x93C) || char(0x200D) || char(0x94D) || "त"</code></p><p><emph>(क + ◌़ + ZWJ + ◌् + त, five characters, one grapheme).</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-concat"><head>fn:concat</head><changes><change issue="701" PR="702" date="2023-09-19">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.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the concatenation of the arguments, treated as sequences of strings.</p></def></gitem><gitem><label>Operator Mapping</label><def><p> The two-argument form of
         this function defines the semantics of the <code nobreak="false">||</code> operator.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="fn" name="concat" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType* ..." default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>, <termref def="dt-focus-independent">focus-independent</termref>,  and <termref def="dt-variadic">variadic</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Unlike all other functions, this function is defined to be variadic, as indicated by the
            ellipsis in the function signature.
            Conceptually, there is an infinite set of functions with different numbers of arguments (minimum arity zero,
            maximum arity unbounded):</p><ulist><item><p><code nobreak="false">concat()</code> returns a zero-length string, <code nobreak="false">""</code>.</p></item><item><p><code nobreak="false">concat("a")</code> returns <code nobreak="false">"a"</code>.</p></item><item><p><code nobreak="false">concat("a", "b")</code> returns <code nobreak="false">"ab"</code>.</p></item><item><p><code nobreak="false">concat("a", "b", "c")</code> returns <code nobreak="false">"abc"</code>.</p></item><item><p><code nobreak="false">concat("a", "b", "c", "d")</code> returns <code nobreak="false">"abcd"</code>.</p></item><item><p>and so on.</p></item></ulist><p>It is equally possible to supply a single argument containing a sequence of strings:</p><ulist><item><p><code nobreak="false">concat(())</code> returns a zero-length string, <code nobreak="false">""</code>.</p></item><item><p><code nobreak="false">concat(("a"))</code> returns <code nobreak="false">"a"</code>.</p></item><item><p><code nobreak="false">concat(("a", "b"))</code> returns <code nobreak="false">"ab"</code>.</p></item><item><p><code nobreak="false">concat(("a", "b", "c"))</code> returns <code nobreak="false">"abc"</code>.</p></item><item><p><code nobreak="false">concat(("a", "b", "c", "d"))</code> returns <code nobreak="false">"abcd"</code>.</p></item><item><p>and so on.</p></item></ulist><p>More generally, any argument can be a sequence of strings:</p><ulist><item><p><code nobreak="false">concat(("a", "b"), "c")</code> returns <code nobreak="false">"abc"</code>.</p></item><item><p><code nobreak="false">concat(("a", "b"), (), ("c", "d"))</code> returns <code nobreak="false">"abcd"</code>.</p></item></ulist><p>A static call on the <function>fn:concat</function> function must use positional arguments,
               it cannot use keywords.</p><p>Each of the parameters has the required type
            <code nobreak="false">xs:anyAtomicType*</code>. The coercion rules ensure that each supplied argument is first converted to
            a sequence of atomic items by applying atomization. These sequences are then combined (by 
            <xtermref spec="XP40" ref="dt-sequence-concatenation">sequence concatenation</xtermref>) 
               into a single sequence, and each item in the combined sequence
            is converted to a string using the <function>fn:string</function> function. The strings are then concatenated
            with no separator.</p><p>If XPath 1.0 compatibility mode is set to true in the static context of a
            static function call to <function>fn:concat</function>, then each supplied argument 
            <code nobreak="false">$v</code> is first reduced to a single
            string, the result of the expression <code nobreak="false">xs:string($v[1])</code>. This rule applies only to
            static function calls.</p><p>A named function reference can be used to create a function item with any arity: for example
         <code nobreak="false">concat#3</code> returns a function item that takes three arguments, which it concatenates.
         Similarly partial function application can be used to construct a function that concatenates fixed and
         variable values: for example <code nobreak="false">concat('[', ?, ']')</code> returns a function item that takes a single
         argument and wraps the string value of this argument in square brackets. Similarly, 
            <code nobreak="false">concat(?, '-', ?)</code> returns a function item of arity two; it returns the string values of
         the two arguments separated by a hyphen.</p></def></gitem><gitem><label>Notes</label><def><note><p>As mentioned in <specref ref="string-types"/> Unicode normalization is not automatically
            applied to the result of <function>fn:concat</function>. If a normalized result is required,
               <function>fn:normalize-unicode</function> can be applied to the <code nobreak="false">xs:string</code>
            returned by <function>fn:concat</function>. The following XQuery:</p><eg xml:space="preserve">
let $v1 := "I plan to go to Mu"
let $v2 := "?nchen in September"
return concat($v1, $v2)</eg><p>where the <code nobreak="false">?</code> represents either the actual Unicode character <char>U+0308</char>
            or the numeric character reference <code nobreak="false">&amp;#x0308;</code>, will return:</p><p>"I plan to go to Mu?nchen in September"</p><p>where the <code nobreak="false">?</code> again represents either the actual Unicode character <char>U+0308</char>
            or the numeric character reference <code nobreak="false">&amp;#x0308;</code>.
            It is worth noting that the returned value is not normalized in NFC; however, it is normalized in NFD.</p><p> However, the following XQuery:</p><eg xml:space="preserve">
let $v1 := "I plan to go to Mu"
let $v2 := "?nchen in September"
return normalize-unicode(concat($v1, $v2))</eg><p>where <code nobreak="false">?</code> represents either the actual Unicode character <char>U+0308</char>
            or the numeric character reference <code nobreak="false">&amp;#x0308;</code>, will return:</p><p><code nobreak="false">"I plan to go to München in September"</code></p><p>This returned result is normalized in NFC.</p><p>Alternatives to the <function>fn:concat</function> function include the concatenation operator
         <code nobreak="false">||</code> (for example <code nobreak="false">$x || '-' || $y</code>), the use of string templates 
         (for example <code nobreak="false">`{ $x }-{ $y }`)</code>, and the <function>fn:string-join</function> function.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">concat('un', 'grateful')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"ungrateful"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">concat(('un', 'grateful'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"ungrateful"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">concat(
  'Thy ', (), 'old ', "groans", "", ' ring',
  ' yet', ' in', ' my', ' ancient',' ears.'
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Thy old groans ring yet in my ancient ears."</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">concat('Ciao!', ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Ciao!"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">concat('Ingratitude, ', 'thou ', ('marble-hearted', ' fiend!'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Ingratitude, thou marble-hearted fiend!"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">concat(01, 02, 03, 04, true())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1234true"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">concat()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">10 || '/' || 6</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"10/6"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-string-join"><head>fn:string-join</head><glist><gitem><label>Summary</label><def><p>Returns a string created by concatenating the items in a sequence, with a defined
            separator between adjacent items.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="string-join" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:anyAtomicType*"/><arg name="separator" type="xs:string?" default="&#34;&#34;" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The coercion rules ensure that the supplied <code nobreak="false">$values</code> argument is first converted to
            a sequence of atomic items by applying atomization.</p><p>The function then returns an <code nobreak="false">xs:string</code> created by casting each item 
            in the atomized sequence to an <code nobreak="false">xs:string</code>, 
            and then concatenating the result strings in order, 
            using the value of <code nobreak="false">$separator</code> as a
            separator between adjacent strings. If <code nobreak="false">$separator</code> is the zero-length
            string, then the items in <code nobreak="false">$values</code> are concatenated without a separator.</p></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$values</code> is the empty sequence, the function returns the
            zero-length string.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $doc := &lt;doc&gt;&lt;chap&gt;&lt;section xml:id="xyz"/&gt;&lt;/chap&gt;&lt;/doc&gt;</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">string-join(1 to 9)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"123456789"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">string-join(('Now', 'is', 'the', 'time', '...'), ' ')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Now is the time ..."</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">string-join(
  ('Blow, ', 'blow, ', 'thou ', 'winter ', 'wind!'),
  ''
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Blow, blow, thou winter wind!"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">string-join((), 'separator')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">string-join(1 to 5, ', ')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1, 2, 3, 4, 5"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">$doc//@xml:id
! string-join((node-name(), '="', ., '"'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'xml:id="xyz"'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">$doc//section
! string-join(ancestor-or-self::*/name(), '/')</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"doc/chap/section"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-substring"><head>fn:substring</head><changes><change issue="895" PR="901" date="2023-12-16">The third argument can now be supplied as the empty sequence.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the part of <code nobreak="false">$value</code> beginning at the position
            indicated by <code nobreak="false">$start</code> and continuing for the number of <termref def="character">characters</termref> indicated by <code nobreak="false">$length</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="substring" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="start" type="xs:double"/><arg name="length" type="xs:double?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns
            the zero-length string. </p><p>Otherwise, the function returns a string comprising those <termref def="character">characters</termref> of <code nobreak="false">$value</code> whose index position (counting
            from one) is greater than or equal to <code nobreak="false">$start</code> (rounded to an
            integer), and (if <code nobreak="false">$length</code> is non-empty) less than the sum of
               <code nobreak="false">$start</code> and <code nobreak="false">$length</code> (both rounded to integers).</p><p>The characters returned do not extend beyond <code nobreak="false">$value</code>. If
               <code nobreak="false">$start</code> is zero or negative, only those characters in positions greater
            than zero are returned.</p><p>More specifically, the three argument version of the function returns the characters in
            <code nobreak="false">$value</code> whose position <code nobreak="false">$p</code> satisfies:</p><p>
            <code nobreak="false">fn:round($start) &lt;= $p and $p &lt; fn:round($start) + fn:round($length)</code>
         </p><p>The two argument version of the function assumes that <code nobreak="false">$length</code> is infinite
            and thus returns the <termref def="character">characters</termref> in
            <code nobreak="false">$value</code> whose position <code nobreak="false">$p</code> satisfies:</p><p>
            <code nobreak="false">fn:round($start) &lt;= $p</code>
         </p><p>In the above computations, the operators such as <code nobreak="false">&lt;=</code> and <code nobreak="false">+</code>
            are evaluated according to the rules of the XPath 4.0 specification.</p></def></gitem><gitem><label>Notes</label><def><note><p>The first character of a string is located at position 1, not position 0.</p><p>The second and third arguments allow <code nobreak="false">xs:double</code> values (rather than
         requiring <code nobreak="false">xs:integer</code>) in order to achieve compatibility with XPath 1.0.</p><p>A surrogate pair counts as one character, not two.</p><p>The consequences of supplying values such as <code nobreak="false">NaN</code> or positive or negative
         infinity for the <code nobreak="false">$start</code> or <code nobreak="false">$length</code> arguments follow from the
         above rules, and are not always intuitive.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("motor car", 6)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">" car"</code></p><p><emph>(Characters starting at position 6 to the end of
                     <code nobreak="false">$sourceString</code> are selected.)</emph></p></td></tr><tr><td colspan="2" rowspan="1"><p/></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("metadata", 4, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"ada"</code></p><p><emph>(Characters at positions greater than or equal to 4 and less than 7 are
                  selected.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("12345", 1.5, 2.6)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"234"</code></p><p><emph>(Characters at positions greater than or equal to 2 and less than 5 are
                  selected.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("12345", 0, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"12"</code></p><p><emph>(Characters at positions greater than or equal to 0 and less than 3 are
                  selected. Since the first position is 1, these are the characters at positions 1
                  and 2.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("12345", 5, -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p><p><emph>(Characters at positions greater than or equal to 5 and less than 2 are
                  selected.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("12345", -3, 5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1"</code></p><p><emph>(Characters at positions greater than or equal to -3 and less than 2
                  are selected. Since the first position is 1, this is the character at position
                  1.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("12345", 0 div 0E0, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p><p><emph>(Since <code nobreak="false">0 div 0E0</code> returns <code nobreak="false">NaN</code>, and
                     <code nobreak="false">NaN</code> compared to any other number returns <code nobreak="false">false</code>, no
                  characters are selected.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("12345", 1, 0 div 0E0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p><p><emph>(As above.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring((), 1, 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("12345", -42, 1 div 0E0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"12345"</code></p><p><emph>(Characters at positions greater than or equal to -42 and less than
                     <code nobreak="false">INF</code> are selected.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring("12345", -1 div 0E0, 1 div 0E0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p><p><emph>(Since the value of <code nobreak="false">-INF + INF</code> is <code nobreak="false">NaN</code>, no
                  characters are selected.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-string-length"><head>fn:string-length</head><changes><change issue="2279" PR="2286" date="2025-11-17">The type of <code nobreak="false">$value</code>
            has been generalized to <code nobreak="false">xs:anyAtomicType?</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the number of <termref def="character">characters</termref> in a string.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="string-length" return-type="xs:integer" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:anyAtomicType?" default="fn:string(.)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the
            <code nobreak="false">xs:integer</code> value <code nobreak="false">0</code>.
            Otherwise, the value is cast to an <code nobreak="false">xs:string</code>, and an <code nobreak="false">xs:integer</code>
            is returned that reflects the number of <termref def="character">characters</termref>
            in the string.</p></def></gitem><gitem><label>Error Conditions</label><def><p>If <code nobreak="false">$value</code> is not specified and the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>, a type error is raised: <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/>.</p><p>As a consequence of the rules given above, a type error is raised 
           <xerrorref spec="XP" class="TY" code="0004" type="type"/> if the context value
            cannot be atomized, or if the result of atomizing the context value is a sequence
            containing more than one atomic item.</p></def></gitem><gitem><label>Notes</label><def><note><p>Unlike some programming languages, a <termref def="codepoint">codepoint</termref>
            greater than 65535 counts as one character, not two.</p><p>There are situations where <code nobreak="false">fn:string-length()</code> has a different effect
            from <code nobreak="false">fn:string-length(.)</code>. These situations all involve nodes with
            non-trivial type annotations. For example:</p><ulist><item><p>If the context value
         is an attribute node typed as an <code nobreak="false">xs:integer</code> with the string value <code nobreak="false">000001</code>,
         then <code nobreak="false">fn:string-length()</code> returns <code nobreak="false">6</code>
            (the length of the string value of the node), while 
            <code nobreak="false">fn:string-length(.)</code> returns 1 (the length of the string that results from converting
            the typed value (1) to a string). In earlier versions of this specification this call would have
            failed with a type error.</p></item><item><p>If the context value is the element node <code nobreak="false">&lt;e&gt; NN &lt;/e&gt;</code>, and has the
            type annotation <code nobreak="false">xs:NCName</code>, then <code nobreak="false">fn:string-length()</code> returns
            4 (the length of the string value of the element node), while <code nobreak="false">fn:string-length(.)</code>
            returns 2 (the length of the typed value of the element node).</p></item><item><p>If the context value is the attribute node <code nobreak="false">ref="A B C"</code>, and has the
            type annotation <code nobreak="false">xs:IDREFS</code>, then <code nobreak="false">fn:string-length()</code> returns
            5 (the length of the string value of the attribute node), while <code nobreak="false">fn:string-length(.)</code>
            raises an error, because the atomized value of the attribute is a sequence of strings,
            and calling the <code nobreak="false">fn:string</code> function on a sequence of strings fails.</p></item></ulist></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">string-length(
  "As long as a piece of string"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">28</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"ᾧ" =&gt; string-length()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"ᾧ" =&gt; normalize-unicode("NFD") =&gt; string-length()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">4</eg><p><emph>(For strings that consist of a base character with combining characters, each combining character is length 1.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">string-length(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-normalize-space"><head>fn:normalize-space</head><changes><change issue="2279" PR="2286" date="2025-11-17">The type of <code nobreak="false">$value</code>
            has been generalized to <code nobreak="false">xs:anyAtomicType?</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">$value</code> with leading and trailing whitespace removed, and
            sequences of internal whitespace reduced to a single space character.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="normalize-space" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:anyAtomicType?" default="string(.)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns a zero-length string.
            Otherwise, the value is cast to an <code nobreak="false">xs:string</code>, and a new string is
            constructed by stripping leading and trailing whitespace from the string, and by
            replacing sequences of one or more adjacent whitespace characters with a single space,
            <char>U+0020</char>.</p><p>The whitespace characters are defined in the metasymbol S (Production 3) of <bibref ref="xml"/>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>If no argument is supplied and the context value is
            <xtermref ref="dt-absent" spec="DM40">absent</xtermref>, a type error is raised
            <xerrorref spec="XP" class="DY" code="0002" type="type"/>.</p><p>As a consequence of the rules given above, a type error is raised 
           <xerrorref spec="XP" class="TY" code="0004" type="type"/> if the context value
            cannot be atomized, or if the result of atomizing the context value is a sequence
            containing more than one atomic item.</p></def></gitem><gitem><label>Notes</label><def><note><p>The definition of whitespace is unchanged in <bibref ref="xml11"/>. It is repeated here
         for convenience:</p><p>
            <code nobreak="false">S ::= (#x20 | #x9 | #xD | #xA)+</code>
         </p><p>There are situations where <code nobreak="false">fn:normalize-space()</code> has a different effect
            from <code nobreak="false">fn:normalize-space(.)</code>. These situations all involve nodes with
            non-trivial type annotations. For example:</p><ulist><item><p>If the context value
         is an attribute node typed as an <code nobreak="false">xs:integer</code> with the string value <code nobreak="false">000001</code>,
         then <code nobreak="false">fn:normalize-space()</code> returns <code nobreak="false">"000001"</code>
            (the string value of the node, whitespace-normalized), while 
            <code nobreak="false">fn:normalize-space(.)</code> returns <code nobreak="false">"1"</code> (the typed value of the node,
            converted to a string and then normalized).</p></item><item><p>If the context value is the attribute node <code nobreak="false">ref=" A  B C "</code>, and has the
            type annotation <code nobreak="false">xs:IDREFS</code>, then <code nobreak="false">fn:normalize-space()</code> returns
            <code nobreak="false">"A B C"</code> (the string value of the attribute node, whitespace-normalized), 
               while <code nobreak="false">fn:normalize-space(.)</code>
            raises an error, because the typed value of the attribute is a sequence of strings,
            and calling the <function>fn:string</function> function on a sequence of strings fails.</p></item></ulist><p>The effect of <code nobreak="false">fn:normalize-space</code> is exactly the same as the effect of
         the <code nobreak="false">whitespace=collapse</code> facet in XSD. Since this facet is implicit for most
         XSD data types (with the notable exception of <code nobreak="false">xs:string</code> itself), nodes that are
         validated against types other than <code nobreak="false">xs:string</code> will tend to be implicitly
         in the form that <function>normalize-string</function> generates. Confusingly,
         the XSD type <code nobreak="false">xs:normalizedString</code> uses the facet <code nobreak="false">whitespace=replace</code>,
         which does <emph>not</emph> have the same effect as the <function>normalize-space</function>
         function: it replaces all whitespace characters by <char>U+0020</char>, but does not remove
         leading or trailing spaces, nor does it merge adjacent spaces.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">normalize-space(" The    wealthy curled darlings
           of    our    nation. ")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"The wealthy curled darlings of our nation."</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">normalize-space(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-normalize-unicode"><head>fn:normalize-unicode</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">$value</code> after applying Unicode normalization.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="normalize-unicode" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="form" type="xs:string?" default="&#34;NFC&#34;" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the
            zero-length string.</p><p>Otherwise, the function returns <code nobreak="false">$value</code> normalized according to
            the rules of the normalization form identified by the value of
               <code nobreak="false">$form</code>.</p><p>The effective value of <code nobreak="false">$form</code> is the value of the expression
               <code nobreak="false">fn:upper-case(fn:normalize-space($form))</code>.</p><ulist><item><p>If the effective value of <code nobreak="false">$form</code> is <quote>NFC</quote>,
                  then the function returns <code nobreak="false">$value</code> converted to Unicode
                  Normalization Form C (NFC).</p></item><item><p>If the effective value of <code nobreak="false">$form</code> is <quote>NFD</quote>,
                  then the function returns <code nobreak="false">$value</code> converted to Unicode
                  Normalization Form D (NFD).</p></item><item><p>If the effective value of <code nobreak="false">$form</code> is <quote>NFKC</quote>,
                  then the function returns <code nobreak="false">$value</code> in Unicode Normalization
                  Form KC (NFKC).</p></item><item><p>If the effective value of <code nobreak="false">$form</code> is <quote>NFKD</quote>,
                  then the function returns <code nobreak="false">$value</code> converted to Unicode
                  Normalization Form KD (NFKD).</p></item><item><p>If the effective value of <code nobreak="false">$form</code> is
                     <quote>FULLY-NORMALIZED</quote>, then the function returns 
                  <code nobreak="false">$value</code> converted to fully normalized form. </p></item><item><p>If the effective value of <code nobreak="false">$form</code> is the zero-length
                  string, no normalization is performed and <code nobreak="false">$value</code> is returned.</p></item></ulist><p>Normalization forms NFC, NFD, NFKC, and NFKD, and the algorithms to be used for
            converting a string to each of these forms, are defined in <bibref ref="UNICODE-TR15"/>.</p><p>The motivation for normalization form FULLY-NORMALIZED is explained in <bibref ref="charmod-normalization"/>. However, as that specification did not progress beyond
            working draft status, the normative specification is as follows:</p><ulist><item><p>A string is <term>fully-normalized</term> if (a) it is in normalization form NFC
                  as defined in <bibref ref="UNICODE-TR15"/>, and (b) it does not start
                  with a composing character.</p></item><item><p>A composing character is a character that is one or both of the following:</p><ulist><item><p>the second character in the canonical decomposition mapping of some
                        character that is not listed in the Composition Exclusion Table defined in
                        <bibref ref="UNICODE-TR15"/>;</p></item><item><p>of non-zero canonical combining class (as defined in <bibref ref="Unicode"/>).</p></item></ulist></item><item><p>A string is converted to FULLY-NORMALIZED form as follows:</p><ulist><item><p>if the first character in the string is a composing character, prepend a
                        single space (x20);</p></item><item><p>convert the resulting string to normalization form NFC.</p></item></ulist></item></ulist><p>Conforming implementations <rfc2119>must</rfc2119> support normalization form <code nobreak="false">NFC</code> and
               <rfc2119>may</rfc2119> support normalization forms <code nobreak="false">NFD</code>, <code nobreak="false">NFKC</code>, <code nobreak="false">NFKD</code>, and
            <code nobreak="false">FULLY-NORMALIZED</code>. They <rfc2119>may</rfc2119> also support other normalization forms
            with <termref def="implementation-defined">implementation-defined</termref> semantics. </p><p>It is <termref def="implementation-defined">implementation-defined</termref> which
            version of Unicode (and therefore, of the normalization algorithms and their underlying
            data) is supported by the implementation. See <bibref ref="UNICODE-TR15"/> for
            details of the stability policy regarding changes to the normalization rules in future
            versions of Unicode. If the input string contains codepoints that are unassigned in the
            relevant version of Unicode, or for which no normalization rules are defined, the
               <function>fn:normalize-unicode</function> function leaves such codepoints unchanged. If the
            implementation supports the requested normalization form then it <rfc2119>must</rfc2119>
            be able to handle every input string without raising an error.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A <phrase>dynamic</phrase> error is raised <errorref class="CH" code="0003"/> if the
            effective value of the <code nobreak="false">$form</code> argument is not one of the values
            supported by the implementation.</p></def></gitem></glist></div3><div3 id="func-upper-case"><head>fn:upper-case</head><glist><gitem><label>Summary</label><def><p>Converts a string to upper case.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="upper-case" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the zero-length string is
            returned.</p><p>Otherwise, the function returns <code nobreak="false">$value</code> after translating every
               <termref def="character">character</termref> to its upper-case correspondent as
            defined in the appropriate case mappings section in the Unicode standard <bibref ref="Unicode"/>. For versions of Unicode beginning with the 2.1.8 update, only
            locale-insensitive case mappings should be applied. Beginning with version 3.2.0 (and
            likely future versions) of Unicode, precise mappings are described in default case
            operations, which are full case mappings in the absence of tailoring for particular
            languages and environments. Every lower-case character that does not have an upper-case
            correspondent, as well as every upper-case character, is included in the returned value
            in its original form. </p></def></gitem><gitem><label>Notes</label><def><note><p>Case mappings may change the length of a string. In general, the
               <function>fn:upper-case</function> and <function>fn:lower-case</function> functions are not inverses
            of each other: <code nobreak="false">fn:lower-case(fn:upper-case($s))</code> is not guaranteed to
            return <code nobreak="false">$s</code>, nor is <code nobreak="false">fn:upper-case(fn:lower-case($s))</code>. The
            character <char>U+0131</char> (used in Turkish) 
             is perhaps the most prominent
            lower-case letter which will not round-trip. The character <char>U+0130</char>
            
            is the most prominent upper-case letter which will not round trip; there are others,
            such as <char>U+1E9E</char>, which was introduced in Unicode 5.1.</p><p> These functions may not always be linguistically appropriate (e.g. Turkish i without
            dot) or appropriate for the application (e.g. titlecase). In cases such as Turkish, a
            simple translation should be used first.</p><p> Because the function is not sensitive to locale, results will not always match user
            expectations. In Quebec, for example, the standard uppercase equivalent of <code nobreak="false">è</code> is <code nobreak="false">È</code>,
            while in metropolitan France it is more commonly <code nobreak="false">E</code>; only one of these is supported by
            the functions as defined.</p><p> Many characters of class Ll lack uppercase equivalents in the Unicode case mapping
            tables; many characters of class Lu lack lowercase equivalents.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">upper-case("abCd0")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"ABCD0"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-lower-case"><head>fn:lower-case</head><glist><gitem><label>Summary</label><def><p>Converts a string to lower case.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="lower-case" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If t<code nobreak="false">$value</code> is the empty sequence, the zero-length string is
            returned.</p><p>Otherwise, the function returns <code nobreak="false">$value</code> after translating every
               <termref def="character">character</termref> to its lower-case correspondent as
            defined in the appropriate case mappings section in the Unicode standard <bibref ref="Unicode"/>. For versions of Unicode beginning with the 2.1.8 update, only
            locale-insensitive case mappings should be applied. Beginning with version 3.2.0 (and
            likely future versions) of Unicode, precise mappings are described in default case
            operations, which are full case mappings in the absence of tailoring for particular
            languages and environments. Every upper-case character that does not have a lower-case
            correspondent, as well as every lower-case character, is included in the returned value
            in its original form. </p></def></gitem><gitem><label>Notes</label><def><note><p>Case mappings may change the length of a string. In general, the
               <function>fn:upper-case</function> and <function>fn:lower-case</function> functions are not inverses
            of each other: <code nobreak="false">fn:lower-case(fn:upper-case($s))</code> is not guaranteed to
            return <code nobreak="false">$s</code>, nor is <code nobreak="false">fn:upper-case(fn:lower-case($s))</code>. The
            character <char>U+0131</char> (used in Turkish) 
            is perhaps the most prominent
            lower-case letter which will not round-trip. The character <char>U+0130</char>
            
            is the most prominent upper-case letter which will not round trip; there are others,
            such as <char>U+1E9E</char>, which was introduced in Unicode 5.1.</p><p> These functions may not always be linguistically appropriate (e.g. Turkish i without
            dot) or appropriate for the application (e.g. titlecase). In cases such as Turkish, a
            simple translation should be used first.</p><p> Because the function is not sensitive to locale, results will not always match user
            expectations. In Quebec, for example, the standard uppercase equivalent of <code nobreak="false">è</code> is <code nobreak="false">È</code>,
            while in metropolitan France it is more commonly <code nobreak="false">E</code>; only one of these is supported by
            the functions as defined.</p><p> Many characters of class Ll lack uppercase equivalents in the Unicode case mapping
            tables; many characters of class Lu lack lowercase equivalents.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">lower-case("ABc!D")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"abc!d"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-translate"><head>fn:translate</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">$value</code> modified by replacing or removing individual
            characters. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="translate" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="replace" type="xs:string"/><arg name="with" type="xs:string"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the
            zero-length string.</p><p>Otherwise, the function returns a result string constructed by processing each <termref def="character">character</termref> in <code nobreak="false">$value</code>, in order,
            according to the following rules:</p><olist><item><p>If the character does not appear in <code nobreak="false">$replace</code> then it
                  is added to the result string unchanged.</p></item><item><p>If the character first appears in <code nobreak="false">$replace</code> at some
                  position <emph>M</emph>, where the value of <code nobreak="false">$with</code> is
                     <emph>M</emph> or more characters in length, then the character at position
                     <emph>M</emph> in <code nobreak="false">$with</code> is added to the result string.</p></item><item><p>If the character first appears in <code nobreak="false">$replace</code> at some
                  position <emph>M</emph>, where <code nobreak="false">$with</code> is less than
                     <emph>M</emph> characters in length, then the character is omitted from the
                  result string.</p></item></olist></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$replace</code> is the zero-length string then the function returns
               <code nobreak="false">$value</code> unchanged.</p><p>If a character occurs more than once in <code nobreak="false">$replace</code>, then the first
            occurrence determines the action taken.</p><p>If <code nobreak="false">$with</code> is longer than <code nobreak="false">$replace</code>, the excess
            characters are ignored.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">translate("bar", "abc", "ABC")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"BAr"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">translate("--aaa--", "abc-", "ABC")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"AAA"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">translate("abcdabc", "abc", "AB")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"ABdAB"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-hash"><head>fn:hash</head><changes><change issue="779 1188 1422 1426" PR="937 995 1190" date="2024-01-23">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the results of a specified hash, checksum, or
            cyclic redundancy check function applied to the input.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="hash" return-type="xs:hexBinary?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:string | xs:hexBinary | xs:base64Binary)?"/><arg name="algorithm" type="xs:string?" default="&#34;MD5&#34;" note="default-on-empty"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>If <code nobreak="false">$value</code> is an instance of <code nobreak="false">xs:string</code>, it is converted to a sequence
            of octets on the basis of UTF-8 encoding. If <code nobreak="false">$value</code> is an instance of
               <code nobreak="false">xs:base64Binary</code> or <code nobreak="false">xs:hexBinary</code>, it is converted to a sequence of
            octets. </p><p>The <code nobreak="false">$algorithm</code> argument determines the algorithm to be used to
            calculate a checksum, hash, or cyclic redundancy check. The effective value of the
            algorithm is determined by passing the value through
            <code nobreak="false">fn:upper-case(fn:normalize-space())</code>. </p><p>Conforming implementations <rfc2119>must</rfc2119> support the following
            options and the functions referred to by them:</p><ulist><item><p><code nobreak="false">MD5</code>: the MD5 Message-Digest algorithm, defined by <bibref ref="rfc6151"/> (update to <bibref ref="rfc1321"/>).</p></item><item><p><code nobreak="false">SHA-1</code>: the SHA-1 algorithm, defined by <bibref ref="fips180-4"/>. </p></item><item><p><code nobreak="false">SHA-256</code>: the SHA-256 algorithm, defined by <bibref ref="fips180-4"/>. </p></item><item><p><code nobreak="false">BLAKE3</code>: the BLAKE3 algorithm defined by <bibref ref="BLAKE3"/>.</p></item><item><p><code nobreak="false">CRC-32</code>: the CRC-32 algorithm, defined by <bibref ref="ieee802-3"/>. It delivers a 32 bit unsigned integer, which this function
               returns as a 4-octet <code nobreak="false">xs:hexBinary</code> value representing this integer in
               big-endian order (that is, most significant byte first).</p><note><p>Some libraries, notably <code nobreak="false">System.IO.Hashing.Crc32</code> in .NET, return
               the result in little-endian order.</p></note></item></ulist><p>Conforming implementations <rfc2119>may</rfc2119> support other checksum and
            hash functions with implementation-defined semantics.
            The <code nobreak="false">$options</code> argument, if present, defines additional parameters
            controlling how the process is conducted.</p><p>The function returns as <code nobreak="false">xs:hexBinary</code> the octets returned by passing
            <code nobreak="false">$value</code> as an octet sequence through the selected algorithm.
            The process is followed even if the input octet sequence is empty.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="HA" code="0001"/> if the effective value of the
            option <code nobreak="false">algorithm</code> is not one of the values supported by the implementation.</p></def></gitem><gitem><label>Notes</label><def><note><p>It is common for secure algorithms to be cryptographically broken, as has happened to
            the algorithms <code nobreak="false">MD5</code>, <code nobreak="false">SHA-1</code>, and <code nobreak="false">SHA-256</code>. 
            And the <code nobreak="false">CRC-32</code> algorithm is not intended for cryptographic purposes. 
            Developers are responsible for ensuring that the algorithm chosen meets any expected
            security protocols, if relevant.</p><p>The <code nobreak="false">BLAKE3</code> algorithm is included in the list of hashing algorithms 
            because at the time of writing it appears to be a promising candidate as a secure and
            fast algorithm  that shows signs of gaining widespread support. 
            However, this is a fast moving field and the community group recognizes that this
            decision might eventually not stand the test of time. 
            As the technology evolves in the future, implementations are free to drop support
            for this algorithm and substitute another that appears to better meet requirements.</p><p>Additional security practices, such as salting, may be applied as a preprocessing step,
            or <code nobreak="false">fn:hash()</code> can be incorporated into more complex functions.</p><p>In most cases, the <code nobreak="false">xs:hexBinary</code> output of the function will be sought in
            string form. Because of serialization rules, casting to a string renders the hash in
            uppercase, and rendering in lowercase (as adopted by <bibref ref="rfc1321"/> and 
            <bibref ref="fips180-4"/>) requires further adjustment.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $doc := &lt;doc&gt;abc&lt;/doc&gt;</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $salt := "D;%yL9TS:5PalS/d"</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("abc")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("900150983CD24FB0D6963F7D28E17F72")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("ABC")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("902FBDD2B1DF0C4F70B4A5D23525E932")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("D41D8CD98F00B204E9800998ECF8427E")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("ABC", "SHA-1")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("3C01BDBB26F358BAB27F267924AA2C9A03FCFDB8")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("ABC", "BLAKE3") 
=&gt; string()
=&gt; lower-case()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"d1717274597cf0289694f75d96d444b992a096f1afd8e7bbfa6ebb1d360fedfc"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("ABC", "BLAKE3") 
=&gt; xs:base64Binary()
=&gt; string()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"0XFydFl88CiWlPddltREuZKglvGv2Oe7+m67HTYP7fw="</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("ABC", "sha-256")
=&gt; string()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("ABC", "sha-256")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("B5D4045C3F466FA91FE2CC6ABE79232A1A57CDF104F7A26E716E0A1E2789DF78")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash($doc)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("900150983CD24FB0D6963F7D28E17F72")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash(serialize($doc), "sha-1") 
=&gt; xs:base64Binary()   
=&gt; string()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"8PzN28NtxQv5RlxQ5/w6DcnrpEU="</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("password123" || $salt, "SHA-256")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("9C9B913EB1B6254F4737CE947EFD16F16E916F9D6EE5C1102A2002E48D4C88BD")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("", "CRC-32")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("00000000")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hash("input", "CRC-32")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:hexBinary("D82832D7")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">hash("password123", "sha-unknown")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Raises error FOHA0001.</p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="substring.functions"><head>Functions based on substring matching</head><p>The functions described in this section examine a string <code nobreak="false">$arg1</code> to see
                    whether it contains another string <code nobreak="false">$arg2</code> as a substring. The result
                    depends on whether <code nobreak="false">$arg2</code> is a substring of <code nobreak="false">$arg1</code>, and
               if so, on the range of <termref def="character">characters</termref> in <code nobreak="false">$arg1</code> which <code nobreak="false">$arg2</code> matches.</p><p>When the <termref def="dt-codepoint-collation">Unicode codepoint collation</termref>
                    is used, this simply involves determining whether <code nobreak="false">$arg1</code> contains a
               contiguous sequence of characters whose <termref def="codepoint">codepoints</termref> are the same, one for one,
                    with the codepoints of the characters in <code nobreak="false">$arg2</code>.</p><p>When a collation is specified, the rules are more complex.</p><p>All collations support the capability of deciding whether two <termref def="string">strings</termref> are
                    considered equal, and if not, which of the strings should be regarded as
                    preceding the other. For functions such as <function>fn:compare</function>, this is
                    all that is required. For other functions, such as <function>fn:contains</function>,
                    the collation needs to support an additional property: it must be able to
                    decompose the string into a sequence of collation units, each unit consisting of
                    one or more characters, such that two strings can be compared by pairwise
                    comparison of these units.</p><p><termdef id="dt-collation-unit" term="collation unit">The term <term>collation unit</term>
            as used in this specification is equivalent to the term <term>collation element</term>
            used in <bibref ref="UNICODE-TR10"/>.</termdef></p><p>The string
                    <var>Q</var> is then considered to contain <var>P</var> as a
                    substring if the sequence of collation units corresponding to <var>P</var>
                    is a subsequence of the sequence of collation units corresponding to
                    <var>Q</var>. The characters in <code nobreak="false">P</code> that match are the
                    characters corresponding to these collation units.</p><p>This rule may occasionally lead to surprises. For example, consider a collation
                    that treats <code nobreak="false">"Jaeger"</code> and <code nobreak="false">"Jäger"</code>
                    as equal. It might do this by treating <code nobreak="false">"ä"</code> as representing
                    two collation units, in which case the
                    expression <code nobreak="false">fn:contains("Jäger", "eg")</code> will return
                    <code nobreak="false">true</code>. Alternatively, a collation might treat "ae" as a single
                    collation unit, in which case the expression <code nobreak="false">fn:contains("Jaeger",
                    "eg")</code> will return <code nobreak="false">false</code>. The results of these functions thus
                    depend strongly on the properties of the collation that is used.</p><p>In addition,
                    collations may specify that some collation units should be ignored during matching. If hyphen is an ignored
					collation unit, then <code nobreak="false">fn:contains("code-point", "codepoint")</code> will be <code nobreak="false">true</code>, 
					and <code nobreak="false">fn:contains("codepoint", "-")</code> will also be <code nobreak="false">true</code>.</p><p> In the rules for the functions defined in this section, we use the following terms
               taken from <bibref ref="UNICODE-TR10"/>:</p><ulist><item><p><termdef id="dt-match.collation" term="match">The term <term>match</term>
               is used in the sense of definition DS2 from <bibref ref="UNICODE-TR10"/>.</termdef></p></item><item><p><termdef id="dt-minimal-match.collation" term="minimal match">The term <term>minimal match</term>
               is used in the sense of definition DS4 from <bibref ref="UNICODE-TR10"/>.</termdef></p></item></ulist><p>In the definitions in <bibref ref="UNICODE-TR10"/>, these rules
               involve a number of parameters. In the context of the functions defined in this
               section, these parameters are interpreted as follows:</p><ulist><item><p>
                     <var>C</var> is the collation; that is, the value of the <code nobreak="false">$collation</code>
                    argument if specified, otherwise the default collation.</p></item><item><p>
                     <var>P</var> is the (candidate) substring, the value of the <code nobreak="false">$substring</code>
                     argument to the function.
                  </p></item><item><p>
                     <var>Q</var> is the (candidate) containing string, the value of the <code nobreak="false">$value</code>
                     argument to the function.
                  </p></item><item><p>The boundary condition <var>B</var> is satisfied at the start and end of a
                    string, and between any two characters that belong to different collation units
                    (“collation elements” in the language of <bibref ref="UNICODE-TR10"/>). It
                    is not satisfied between two characters that belong to the same collation unit.</p></item></ulist><p>It is possible to define collations that do not have the ability to decompose a
                    string into units suitable for substring matching. An argument to a function
                    defined in this section may be a URI that identifies a collation that is able to
                    compare two strings, but that does not have the capability to split the string
                    into collation units. Such a collation may cause the function to fail, or to
                    give unexpected results, or it may be rejected as an unsuitable argument. The
                    ability to decompose strings into collation units is an 
               <termref def="implementation-defined"/> property of the collation.
            The <function>fn:collation-available</function> function can be used to ask
            whether a particular collation has this property.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:contains</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the string <code nobreak="false">$value</code> contains <code nobreak="false">$substring</code> as a
            substring, taking collations into account.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:starts-with</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the string <code nobreak="false">$value</code> contains <code nobreak="false">$substring</code> as a leading
            substring, taking collations into account.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:ends-with</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the string <code nobreak="false">$value</code> contains <code nobreak="false">$substring</code> as a trailing
            substring, taking collations into account.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:substring-before</code></td><td rowspan="1" colspan="1">Returns the part of <code nobreak="false">$value</code> that precedes the first occurrence of
               <code nobreak="false">$substring</code>, taking collations into account.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:substring-after</code></td><td rowspan="1" colspan="1">Returns the part of <code nobreak="false">$value</code> that follows the first occurrence of
               <code nobreak="false">$substring</code>, taking collations into account.</td></tr></tbody></table><div3 id="func-contains"><head>fn:contains</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the string <code nobreak="false">$value</code> contains <code nobreak="false">$substring</code> as a
            substring, taking collations into account.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="contains" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="substring" type="xs:string?"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> or <code nobreak="false">$substring</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p><p>If <code nobreak="false">$substring</code> is the zero-length string, then the function returns
               <code nobreak="false">true</code>.</p><p>If <code nobreak="false">$value</code> is the zero-length string, the function returns
               <code nobreak="false">false</code>.</p><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>The function returns an <code nobreak="false">xs:boolean</code> indicating whether or not 
               <code nobreak="false">$value</code> contains (at the beginning, at the end, or anywhere within) at
            least one sequence of collation units that provides a <termref def="dt-minimal-match.collation"/> to the
            collation units in <code nobreak="false">$substring</code>, according to the collation that is
            used.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A <phrase>dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the specified collation does not support collation units.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $coll := 
"http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary"</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>The collation used in some of these examples, <code nobreak="false">$coll</code>, is a
               collation in which both <code nobreak="false">-</code> and <code nobreak="false">*</code> are ignorable collation units.</p></td></tr><tr><td colspan="2" rowspan="1"><p>“Ignorable collation unit” is equivalent to “ignorable collation element” in <bibref ref="UNICODE-TR10"/>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">contains("tattoo", "t")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">contains("tattoo", "ttt")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">contains("", ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p><p><emph>(The first rule is applied, followed by the second
                  rule.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains(
  "abcdefghi",
  "-d-e-f-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains(
  "a*b*c*d*e*f*g*h*i*",
  "d-ef-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains(
  "abcd***e---f*--*ghi",
  "def",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">contains(
  (),
  "--***-*---",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-starts-with"><head>fn:starts-with</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the string <code nobreak="false">$value</code> contains <code nobreak="false">$substring</code> as a leading
            substring, taking collations into account.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="starts-with" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="substring" type="xs:string?"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> or <code nobreak="false">$substring</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p><p>If <code nobreak="false">$substring</code> is the zero-length string, then the function returns
               <code nobreak="false">true</code>. If <code nobreak="false">$value</code> is the zero-length string and
            <code nobreak="false">$substring</code> is not the zero-length string, then the function returns
               <code nobreak="false">false</code>.</p><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>The function returns an <code nobreak="false">xs:boolean</code> indicating whether or not 
               <code nobreak="false">$value</code> starts with a sequence of collation units that provides a
               <termref def="dt-match.collation"/> to the collation units of <code nobreak="false">$substring</code> according to the
            collation that is used.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A <phrase>dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the specified collation does not support collation units.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $coll := 
"http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary"</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>The collation used in some of these examples, <code nobreak="false">$coll</code>, is a
               collation in which both <code nobreak="false">-</code> and <code nobreak="false">*</code> are ignorable collation units.</p></td></tr><tr><td colspan="2" rowspan="1"><p>“Ignorable collation unit” is equivalent to “ignorable collation element” in <bibref ref="UNICODE-TR10"/>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">starts-with("tattoo", "tat")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">starts-with("tattoo", "att")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">starts-with((), ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with(
  "abcdefghi",
  "-a-b-c-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with(
  "a*b*c*d*e*f*g*h*i*",
  "a-bc-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with(
  "abcd***e---f*--*ghi",
  "abcdef",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with(
  (),
  "--***-*---",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">starts-with(
  "-abcdefghi",
  "-abc",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-ends-with"><head>fn:ends-with</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the string <code nobreak="false">$value</code> contains <code nobreak="false">$substring</code> as a trailing
            substring, taking collations into account.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="ends-with" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="substring" type="xs:string?"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> or <code nobreak="false">$substring</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p><p>If <code nobreak="false">$substring</code> is the zero-length string, then the function returns
               <code nobreak="false">true</code>. If <code nobreak="false">$value</code> is the zero-length string and
            the value of <code nobreak="false">$substring</code> is not the zero-length string, then the function returns
               <code nobreak="false">false</code>.</p><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>The function returns an <code nobreak="false">xs:boolean</code> indicating whether or not 
               <code nobreak="false">$value</code> ends with a sequence of collation units that provides a
               <termref def="dt-match.collation"/> to the collation units of <code nobreak="false">$substring</code> according to the
            collation that is used.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A <phrase>dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the specified collation does not support collation units.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $coll := 
"http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary"</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>The collation used in some of these examples, <code nobreak="false">$coll</code>, is a
               collation in which both <code nobreak="false">-</code> and <code nobreak="false">*</code> are ignorable collation units.</p></td></tr><tr><td colspan="2" rowspan="1"><p>“Ignorable collation unit” is equivalent to “ignorable collation element” in <bibref ref="UNICODE-TR10"/>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">ends-with("tattoo", "tattoo")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">ends-with("tattoo", "atto")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">ends-with((), ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with(
  "abcdefghi",
  "-g-h-i-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with(
  "abcd***e---f*--*ghi",
  "defghi",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with(
  "abcd***e---f*--*ghi",
  "defghi",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with(
  (),
  "--***-*---",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">ends-with(
  "abcdefghi",
  "ghi-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-substring-before"><head>fn:substring-before</head><glist><gitem><label>Summary</label><def><p>Returns the part of <code nobreak="false">$value</code> that precedes the first occurrence of
               <code nobreak="false">$substring</code>, taking collations into account.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="substring-before" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="substring" type="xs:string?"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p> If <code nobreak="false">$value</code> or <code nobreak="false">$substring</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p><p>If <code nobreak="false">$substring</code> is the zero-length string, then the function returns
            the zero-length string. </p><p>If <code nobreak="false">$value</code> does not contain a string that is equal to 
            <code nobreak="false">$substring</code>, then the function returns the zero-length string. </p><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>The function returns the substring of <code nobreak="false">$value</code> that precedes in
            <code nobreak="false">$value</code> the first occurrence of a sequence of collation units
            that provides a <termref def="dt-minimal-match.collation"/> to the collation units of <code nobreak="false">$substring</code>
            according to the collation that is used.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A <phrase>dynamic</phrase> error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if the specified collation does not support collation units.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $coll := 
"http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary"</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>The collation used in some of these examples, <code nobreak="false">$coll</code>, is a
               collation in which both <code nobreak="false">-</code> and <code nobreak="false">*</code> are ignorable collation units.</p></td></tr><tr><td colspan="2" rowspan="1"><p>“Ignorable collation unit” is equivalent to “ignorable collation element” in <bibref ref="UNICODE-TR10"/>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring-before("tattoo", "attoo")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"t"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring-before("tattoo", "tatto")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring-before((), ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">substring-before(
  "abcdefghi",
  "--d-e-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"abc"</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">substring-before(
  "abc--d-e-fghi",
  "--d-e-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"abc--"</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">substring-before(
  "a*b*c*d*e*f*g*h*i*",
  "***cde",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"a*b*"</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">substring-before(
  "Eureka!",
  "--***-*---",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">""</eg><p><emph>(The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-substring-after"><head>fn:substring-after</head><glist><gitem><label>Summary</label><def><p>Returns the part of <code nobreak="false">$value</code> that follows the first occurrence of
               <code nobreak="false">$substring</code>, taking collations into account.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="substring-after" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="substring" type="xs:string?"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> or <code nobreak="false">$substring</code> is the empty sequence, or
            contains only ignorable collation units, it is interpreted as the zero-length
            string.</p><p>If <code nobreak="false">$substring</code> is the zero-length string, then the function returns
            the value of <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> does not contain a string that is equal to 
            <code nobreak="false">$substring</code>, then the function returns the zero-length string. </p><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>.</p><p>The function returns the substring of <code nobreak="false">$value</code> that follows in
             <code nobreak="false">$value</code> the first occurrence of a sequence of collation units
            that provides a <termref def="dt-minimal-match.collation"/> to the collation units of <code nobreak="false">$substring</code>
            according to the collation that is used. </p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error <rfc2119>may</rfc2119> be raised <errorref class="CH" code="0004"/> if
            the specified collation does not support collation units.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $coll := 
"http://www.w3.org/2013/collation/UCA?lang=en;alternate=blanked;strength=primary"</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>The collation used in some of these examples, <code nobreak="false">$coll</code>, is a
               collation in which both <code nobreak="false">-</code> and <code nobreak="false">*</code> are ignorable collation units.</p></td></tr><tr><td colspan="2" rowspan="1"><p>“Ignorable collation unit” is equivalent to “ignorable collation element” in <bibref ref="UNICODE-TR10"/>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring-after("tattoo", "tat")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"too"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring-after("tattoo", "tattoo")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">substring-after((), ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">substring-after(
  "abcdefghi",
  "--d-e-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"fghi"</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">substring-after(
  "abc--d-e-fghi",
  "--d-e-",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"-fghi"</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">substring-after(
  "a*b*c*d*e*f*g*h*i*",
  "***cde***",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"*f*g*h*i*"</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">substring-after(
  "Eureka!",
  "--***-*---",
  $coll
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Eureka!"</eg><p><emph>(The second argument contains only ignorable collation units and is
                  equivalent to the zero-length string.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="string.match"><head>Regular expressions</head><p>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.</p><div2 id="regex-syntax"><head>Regular expression syntax</head><changes><change issue="999" PR="1022" date="2024-02-20">
                     Regular expressions can include comments (starting and ending with <code nobreak="false">#</code>)
                     if the <code nobreak="false">c</code> flag is set.
                  </change><change issue="998 1006" PR="1856">
                     Word boundaries can be matched. Lookahead and lookbehind assertions are supported.
                     Assertions (including <code nobreak="false">^</code> and <code nobreak="false">$</code>) can no longer be followed
                     by a quantifier.
                  </change></changes><p>The regular expression syntax used by these functions is defined in terms of
                        the regular expression syntax specified in XSD 1.1 (see <bibref ref="xmlschema11-2"/>), 
                  which in turn is based on the established conventions of
                        languages such as Perl. However, because XML Schema uses regular expressions
                        only for validity checking, it omits some facilities that are widely used
                        with other languages. XPath, therefore, extends
                        the XML Schema regular expression syntax to reinstate some of these capabilities.</p><note><p>
                   Implementers should consult <bibref ref="UNICODE-TR18"/> for information on using 
                     regular expression processing on Unicode characters.</p></note><p>The regular expression syntax and semantics are identical to those
                            defined in <bibref ref="xmlschema11-2"/> with the additions described in the 
                  following subsections.</p><note><p>In <bibref ref="xmlschema11-2"/> there are no substantive technical changes
                  to the syntax or semantics of regular expressions relative to <bibref ref="xmlschema-2"/>, but a number
                  of errors and ambiguities have been resolved. For example, the rules for the 
                  interpretation of hyphens within square brackets in a regular expression have been 
                  clarified; and the semantics of regular expressions are no longer tied to a specific 
                  version of Unicode.</p><p>XSD 1.1 is therefore used as the specification baseline, 
                     even for processors that only support XSD 1.0.</p></note><div3 id="id-regex-processing-model"><head>Processing model for regular expressions</head><p>As well as extending the XSD 1.1 syntax for regular expressions, this specification
                  also extends the processing model.</p><p>In XSD, a regular expression is defined to denote a set of strings, and the
                  only functionality offered is to test whether a string matches a regular expression:
                  that is, whether it is a member of the set of strings denoted by the regular expression.</p><p>In this specification, matching a string <var>S</var> against a regular expression delivers a more
                  complex outcome.</p><p>First some terminology:</p><ulist><item><p><termdef id="dt-character-position" term="character position">A string of
                     length <var>N</var> has <var>N+1</var> <term>character positions</term>: one immediately before
                     each character in the string, and one after the last character. In interfaces where
                     character positions are exposed, they are numbered from 1 to <var>N+1</var>.</termdef></p></item><item><p><termdef id="dt-segment" term="segment">A <term>segment</term> of a string <var>S</var> is
                     a sequence of zero or more contiguous characters starting at a given 
                     <termref def="dt-character-position"/> within <var>S</var>.</termdef> 
                        Segments of a string are uniquely identified by 
                     their start position and length. The sequence of characters making up a segment
                     is referred to as the <term>string value</term> of the segment.</p></item><item><p><termdef id="dt-end-position" term="end position">The <term>end position</term> 
                        of a segment is the start position of the segment plus its length.</termdef></p></item></ulist><p>The operation of matching a string <var>S</var> against a regular expression delivers:</p><ulist><item><p>A set of matching <termref def="dt-segment">segments</termref>. 
                        The string <var>S</var> as a whole is said to match the regular
                     expression if the set of matching segments is non-empty.</p></item><item><p>For each matching <termref def="dt-segment"/> <var>M</var>, a collection
                        of <term>captured groups</term>. This is a mapping from positive integers to segments. 
                        The integer is called the group number, and corresponds to the ordinal sequence
                        of opening parentheses of capturing subexpressions within the regular
                        expression, as explained below. The corresponding segment is always a segment of <var>S</var>,
                        but in the case of capturing expressions within lookahead assertions, it is
                        not necessarily a segment of <var>M</var>.</p></item></ulist><p>The semantics of particular constructs in a regular expression are affected by
                  a set of flags. The available flags and their effect are defined in <specref ref="flags"/>.</p><p>The different functions available, such as <function>fn:replace</function>
                  and <code nobreak="false">fn:tokenize</code>, are defined in terms of this outcome. For example:</p><ulist><item><p>The function <function>fn:matches</function> returns true if
                     the set of matching segments is non-empty.</p></item><item><p>The function <function>fn:replace</function> replaces matching
                     segments of the input string with a replacement string.</p></item><item><p>The function <function>fn:tokenize</function> returns the
                     segments of the input string that appear between the matching segments.</p></item></ulist><p>In principle the set of segments that match a regular expression can be determined
                  by enumerating all the segments of the input string and examining each one independently to establish whether
                  it matches. In practice, however:</p><ulist><item><p>If several matching segments have the same starting position, then only one of them
                        is returned. This is chosen as follows:</p><ulist><item><p>In the case of a choice (operator <code nobreak="false">"|"</code>) the first matching
                           branch is chosen.</p></item><item><p>In the case of a repetition with a greedy quantifier (for example <code nobreak="false">"+"</code>
                           or <code nobreak="false">"*"</code>) the longest matching segment is chosen.</p></item><item><p>In the case of a repetition with a reluctant quantifier (for example <code nobreak="false">"+?"</code>
                           or <code nobreak="false">"*?"</code>) the shortest matching segment is chosen.</p></item></ulist></item><item><p>A matching segment is not included in the result if it overlaps an earlier matching
                     segment: specifically, a segment with start position <var>S1</var> is excluded if there
                     is a segment that has start position <var>S0</var> and length <var>L0</var>, where
                     <code nobreak="false"><var>S0</var> &lt; <var>S1</var> &lt; <var>S0</var>+<var>L0</var></code>.</p></item></ulist><note><p>Two segments can be adjacent: that is, the start position of one <termref def="dt-segment"/>
                  can be equal to the <termref def="dt-end-position"/> of the previous segment. This is true even when
                  the second segment is zero-length (the two segments are not considered to be overlapping, even
                  though they have the same <termref def="dt-end-position"/>). This means,
                  for example, that the regular expression <code nobreak="false">a*(?=x)</code> has two non-overlapping matches against
                  the string <code nobreak="false">aaax</code>, one at position 1 and the other at position 4.</p></note><p><termdef id="dt-disjoint-matching-segments" term="disjoint matching segments">The
                  <term>disjoint matching segments</term> obtained by applying a regular expression <var>R</var>
                  to a string <var>S</var> in the presence of a set of flags <var>F</var> are the
                  <termref def="dt-segment">segments</termref> of <var>S</var> that match <var>R</var>
                  (using flags <var>F</var>), after elimination of overlapping segments.</termdef></p><p>The semantics of a regular expression are thus defined by stating which segments
                  of an input string it matches, and what the captured groups corresponding to this match are.
                  This is defined recursively for each construct that may appear within a regular expression,
                  in terms of the outcome of applying its subexpressions.</p><p>For constructs defined in XSD 1.1 (<code nobreak="false">branch</code>, <code nobreak="false">piece</code>,
                  <code nobreak="false">NormalChar</code>, <code nobreak="false">charClass</code>), XSD defines a set of strings
                  denoted by the construct. The corresponding semantics for this specification
                  are that the segments matched by such a construct are the segments whose string value
                  is contained in this set.</p><p>For constructs added to the XSD 1.1 baseline by this specification, the semantics
                  are defined in the sections that follow.</p></div3><div3 id="regex-comments"><head>Comments</head><p>Comments are enabled in regular expressions if the <code nobreak="false">c</code> flag is present.</p><p>A comment starts with a <code nobreak="false">#</code> character that is not escaped with an immediately
                  preceding backslash, and that is not contained in a <code nobreak="false">CharClassExpr</code> (that is,
                  in square brackets). It ends with the following <code nobreak="false">#</code> character, or with the
                  end of the string containing the regular expression.</p><p>Whether or not the <code nobreak="false">c</code> flag is present, the production for
                     <code nobreak="false">SingleCharEsc</code> allows the <code nobreak="false">#</code> character 
                     to be escaped.
                  </p></div3><div3 id="id-regex-grammar"><head>Regular expression grammar</head><p>The grammar for regular expressions is summarized here. Rules that 
                  differ from their definition in XSD 1.1 are marked with the character <code nobreak="false">§</code>
                     against their names.</p><p>In these rules the notation<code nobreak="false">【abc】</code>matches
                     any of the characters <code nobreak="false">'a'</code>, <code nobreak="false">'b'</code>, or <code nobreak="false">'c'</code>,
                     while <code nobreak="false">【0➜9】</code> matches any character whose Unicode codepoint is within a given range, 
                     and <code nobreak="false">¬【abc】</code> matches any character other than <code nobreak="false">'a'</code>, <code nobreak="false">'b'</code>, or <code nobreak="false">'c'</code>.
                     These symbols are used in place of the more conventional notation to allow special characters
                     such as square brackets and hyphens to appear directly without escaping. Within
                     the lenticular brackets, all characters other than <code nobreak="false">➜</code> (including hyphen and backslash)
                     represent themselves.</p><eg xml:space="preserve">
regExp              ::= branch ( '|' branch )*
branch              ::= piece*
piece               ::= (atom quantifier?) | assertion
§quantifier         ::= ( 【?*+】 | ( '{' quantity '}' ) ) '?'?
quantity            ::= quantRange | quantMin | QuantExact
quantRange          ::= QuantExact ',' QuantExact
quantMin            ::= QuantExact ','
QuantExact          ::= 【0➜9】+
§atom               ::= NormalChar | charClass | ( '(' '?:'? regExp ')' ) | backReference 
NormalChar          ::= ¬【.\?*+{}()|[]】	
charClass           ::= SingleCharEsc | charClassEsc | charClassExpr | WildcardEsc
charClassExpr       ::= '[' charGroup ']'
charGroup           ::= ( posCharGroup | negCharGroup ) ( '-' charClassExpr )?
posCharGroup        ::= ( charGroupPart )+
negCharGroup        ::= '^' posCharGroup  
charGroupPart       ::= singleChar | charRange | charClassEsc
singleChar          ::= SingleCharEsc | SingleCharNoEsc
charRange           ::= singleChar '-' singleChar
SingleCharNoEsc     ::= ¬【\[]】
charClassEsc        ::= ( MultiCharEsc | catEsc | complEsc )
§SingleCharEsc      ::= '\' 【nrt\|.?*+(){}$-[]^#】	
catEsc              ::= '\p{' charProp '}'
complEsc            ::= '\P{' charProp '}'
charProp            ::= IsCategory | IsBlock
IsCategory          ::= Letters | Marks | Numbers | Punctuation 
                        | Separators | Symbols | Others
Letters             ::= 'L' 【ultmo】?
Marks               ::= 'M' 【nce】?
Numbers             ::= 'N' 【dlo】?
Punctuation         ::= 'P' 【cdseifo】?
Separators          ::= 'Z' 【slp】?
Symbols             ::= 'S' 【mcko】?
Others              ::= 'C' 【cfon】?
IsBlock             ::= 'Is' 【a➜zA➜Z0➜9-】+
MultiCharEsc        ::= '\' 【sSiIcCdDwW】
WildcardEsc         ::= '.'
§assertion          ::= startOfString | endOfString | wordBoundary 
                        | positiveLookahead | negativeLookahead 
                        | positiveLookbehind | negativeLookbehind
§startOfString      ::= '^'
§endOfString        ::= '$'
§wordBoundary       ::= '\b' | '\B'
§backReference      ::= '\' 【1➜9】【0➜9】*
§positiveLookahead  ::= '(?=' regExp ')' 
                        | '(*positive_lookahead:' regExp ')'
§negativeLookahead  ::= '(?!' regExp ')' 
                        | '(*negative_lookahead:' regExp ')'
§positiveLookbehind ::= '(?&lt;=' simpleRegExp ')' 
                        | '(*positive_lookbehind:' simpleRegExp ')'
§negativeLookbehind ::= '(?&lt;!' simpleRegExp ')' 
                        | '(*negative_lookbehind:' simpleRegExp ')'
§simpleRegExp       ::= simplePiece ( '|' simplePiece )*
§simplePiece        ::= (NormalChar | charClass)*
                     </eg><p>This grammar applies to the regular expression after removal of whitespace and comments
                 if enabled by the <code nobreak="false">x</code> and <code nobreak="false">c</code> flags respectively: see
                 <specref ref="flags"/>.</p><p>XSD 1.1 defines additional rules to disambiguate this grammar.</p></div3><div3 id="reluctant-quantifiers"><head>Reluctant quantifiers</head><p><emph>Reluctant quantifiers</emph> are supported. They are
                                    indicated by a  <code nobreak="false">?</code>
                                     following a quantifier. Specifically:</p><ulist><item><p><code nobreak="false">X??</code> matches X, once or not at all</p></item><item><p><code nobreak="false">X*?</code> matches X, zero or more times</p></item><item><p><code nobreak="false">X+?</code> matches X, one or more times</p></item><item><p><code nobreak="false">X{n}?</code> matches X, exactly n times</p></item><item><p><code nobreak="false">X{n,}?</code> matches X, at least n times</p></item><item><p><code nobreak="false">X{n,m}?</code> matches X, at least n times, but
                                            not more than m times</p></item></ulist><p>Quantifiers that are not <term>reluctant</term> are referred to
                     as <term>greedy</term>.</p><p>When a quantifier appears at the outermost level of a regular
                     expression, the distinction between greedy and reluctant quantifiers
                     affects the set of matching segments delivered by the matching operation.
                     With a greedy quantifier, the longest matching segment at a given start position is
                     returned; with a reluctant quantifier, the shortest matching segment at
                     a given start position is returned.</p><p>When a quantifier appears within a subexpression, the quantified subexpression
                        matches the <emph>shortest</emph> possible substring consistent
                                    with the match as a whole succeeding if the quantifier is
                                    reluctant, or the <emph>longest</emph> possible substring consistent
                                    with the match as a whole succeeding if the quantifier is
                                    greedy.</p><note><p>Reluctant quantifiers have no effect on the results of the
                            boolean <function>fn:matches</function> function, since this
                            function is only interested in discovering whether a matching segment
                            exists, regardless of its start position and length.</p></note></div3><div3 id="captured-subexpressions"><head>Captured groups</head><p>The regular expression syntax defined by <bibref ref="xmlschema-2"/> 
						      allows a regular expression to contain parenthesized subexpressions, but attaches no special
                        significance to them. Some operations associated with regular expressions (for example,
                           back-references, and the <function>fn:replace</function> function) allow access to the parts of the
                           input string that matched a parenthesized subexpression (called captured groups).</p><p><termdef id="dt-capturing-subexpression" term="capturing subexpression">A 
                        left parenthesis is recognized as a capturing left parenthesis provided 
                        it is not immediately followed by <code nobreak="false">?</code> or <code nobreak="false">*</code> (see below), 
                        is not within a character group (square brackets), 
                        and is not escaped with a backslash. The sub-expression enclosed by a capturing left 
                        parenthesis and its matching right parenthesis is referred to as a <term>capturing subexpression</term>.</termdef></p><p>More specifically, the <termref def="dt-capturing-subexpression"/> 
                        enclosed by the <var>N</var>th capturing left parenthesis within the regular expression (determined by
                        its character position in left-to-right order, and
                        counting from one) is referred to as the <var>N</var>th capturing subexpression.
                     </p><p>For example, in the regular expression <code nobreak="false">A(BC(?:D(EF(GH[()]))))</code>, the 
                        subexpression <code nobreak="false">BC(?:D(EF(GH[()])))</code> is capturing subexpression 1, the string
                        subexpression <code nobreak="false">EF(GH[()])</code> is capturing subexpression 2, and the subexpression
                        <code nobreak="false">GH[()]</code> is capturing subexpression 3.
                     </p><p>When, in the course of evaluating a regular expression, a particular <termref def="dt-segment"/> of the input
                     matches a capturing subexpression, that segment becomes available as a <term>captured group</term>.
                        The segment matched by the <var>N</var>th capturing subexpression is referred to as the 
                        <var>N</var>th captured group. By convention, the segment captured by the entire
                        regular expression is treated as captured group 0 (zero).</p><p>When a <termref def="dt-capturing-subexpression"/> is matched
                        more than once (because it is within a construct that allows repetition), then
                        only the last substring that it matched will be captured. Note that this rule
                        is not sufficient in all cases to ensure an unambiguous result, especially in
                        cases where (a) the regular expression contains nested repeating constructs,
                        and/or (b) the repeating construct matches a zero-length string. In such cases
                        it is implementation-dependent which substring is captured. For example given
                        the regular expression <code nobreak="false">(a*)+</code> and the input string <code nobreak="false">"aaaa"</code>, an implementation
                        might legitimately capture either <code nobreak="false">"aaaa"</code> or a zero length string as the content
                        of the captured subgroup.</p><p>Parentheses that are required to group terms within the regular expression, but which are
                        not required for capturing of substrings, can be represented using
                        the syntax <code nobreak="false">(?:xxxx)</code>.</p><p>In the absence of back-references (see below), 
                        the presence of the optional <code nobreak="false">?:</code> has no effect on the set of strings
                     that match the regular expression, but causes the left parenthesis not to be counted
                     by operations (such as <function>fn:replace</function> and back-references) that number the capturing sub-expressions 
                        within a regular expression.</p></div3><div3 id="back-references"><head>Back-references</head><p> Back-references are allowed 
			    outside a character class expression. 
				A back-reference is an additional kind of atom.
				The construct <code nobreak="false">\N</code> where
                <code nobreak="false">N</code> is a single digit is always recognized as a
                back-reference; if this is followed by further digits, these
                digits are taken to be part of the back-reference if and only if
                the resulting number <var>NN</var> is such that
				    the back-reference is preceded by the opening parenthesis of the <var>NN</var>th 
                capturing left parenthesis.
				The regular expression is invalid if a back-reference refers to a
				capturing sub-expression that does not exist or whose
                closing right parenthesis occurs after the back-reference.
                     </p><p>A back-reference with number <var>N</var> matches a string that is the same as
                        the value of the <code nobreak="false">N</code>th captured substring.</p><p>For example, the regular expression
                <code nobreak="false">('|").*\1</code> matches a sequence of characters
                delimited either by an apostrophe at the start and end, or by a
                quotation mark at the start and end. </p><p>If no string has been matched by the <code nobreak="false">N</code>th capturing 
               sub-expression, the back-reference is interpreted as matching 
               a zero-length string.</p><note><p>
                           Within a character class expression, 
                              <code nobreak="false">\</code> followed by a digit is invalid.
			 Some other regular expression languages interpret this as an octal character reference.
                        </p></note></div3><div3 id="unicode-block-names"><head>Unicode block names</head><p>A regular expression that uses a Unicode block name that is not defined in the version(s) of Unicode
                     supported by the processor (for example <code nobreak="false">\p{IsBadBlockName}</code>) is deemed to be invalid
                        <errorref class="RX" code="0002"/>.</p><note><p>XSD 1.0 does not say how this situation should be handled; XSD 1.1
                        says that it should be handled by treating all characters as matching.</p></note></div3><div3 id="id-assertions"><head>Assertions</head><p>Assertions (sometimes called <emph>zero-width assertions</emph>) test whether a particular
                  condition applies at the current position in the input string (resulting in either a match or a no-match),
                  but they do not cause any change to the current position.</p><p>Assertions fall into the following categories:</p><ulist><item><p>The <code nobreak="false">startOfString</code> assertion <code nobreak="false">^</code> tests whether the current
                        position is at the start of the string.</p></item><item><p>The <code nobreak="false">endOfString</code> assertion <code nobreak="false">$</code> tests whether the current position
                        is at the end of the string.</p></item><item><p>The <code nobreak="false">boundary</code> assertions <code nobreak="false">\b</code> and <code nobreak="false">\B</code> test 
                     whether the current position is at the start or end of a word.</p></item><item><p>The positive and negative lookahead assertions test whether there is (or is not) a substring
                     starting at the current position that matches a given regular expression.</p></item><item><p>The positive and negative lookbehind assertions test whether there is (or is not) a substring
                     ending at the current position that matches a given regular expression.</p></item></ulist><p>An assertion <rfc2119>must not</rfc2119> be followed by a quantifier.</p><note><p>Previous versions of this specification allowed a quantifier to follow the 
                     <code nobreak="false">startOfString</code> and <code nobreak="false">endOfString</code> assertions, though this
                     served no practical purpose. Processors <rfc2119>may</rfc2119> provide an option to allow quantifiers
                     to be used in this situation in order to preserve backward compatibility.</p></note><div4 id="matching-start-and-end"><head>Matching the Start and End of the String</head><p>Two meta-characters, <code nobreak="false">^</code> and <code nobreak="false">$</code> are
                        added. By default, the meta-character <code nobreak="false">^</code> matches if the current position is the
                        start of the entire string, while <code nobreak="false">$</code> matches if the current position is the end
                        of the entire string. In multi-line mode, <code nobreak="false">^</code> matches
                        the start of any line (that is, the start of the entire string,
                        and the position immediately after a newline character), while
                        <code nobreak="false">$</code> matches the end of any line (that is, the end of
                        the entire string, and the position immediately before a newline
                        character). Newline here means the character <char>U+000A</char> only.</p><p>Single character escapes are extended to allow the
                        <code nobreak="false">$</code> character to be escaped.</p></div4><div4 diff="add" at="issue1006" id="regex-boundary-assertions"><head>Boundary assertions</head><p>The assertion <code nobreak="false">\b</code> matches at any position where one of the following conditions is true:</p><ulist><item><p>The current position is the start of the string, the string is not empty, and the first
                       character in the string matches <code nobreak="false">\w</code>.</p></item><item><p>The current position is the end of the string, the string is not empty, and the
                       last character in the string matches <code nobreak="false">\w</code>.</p></item><item><p>The character before the current position matches <code nobreak="false">\w</code> and the character
                    after the current position matches <code nobreak="false">\W</code>.</p></item><item><p>The character before the current position matches <code nobreak="false">\W</code> and the character
                    after the current position matches <code nobreak="false">\w</code>.</p></item></ulist><p>Informally, <code nobreak="false">\b</code> matches if the current position is the start or end
                 of a word, where a word is defined as a sequence of consecutive characters other than
                 codepoints in Unicode groups <code nobreak="false">P</code> (punctuation), <code nobreak="false">Z</code> (separator),
                 or <code nobreak="false">C</code> (other).</p><p>The assertion <code nobreak="false">\B</code> matches at any position where <code nobreak="false">\b</code> does not match.</p></div4><div4 id="regex-positive-lookahead"><head>Positive Lookahead Assertions</head><p>There are two equivalent ways of writing a positive lookahead assertion:</p><p><code nobreak="false">(?=<var>xyz</var>)</code></p><p><code nobreak="false">(*positive_lookahead:<var>xyz</var>)</code></p><p>In both cases, the assertion matches at a particular position in the input string
		          only if there is a substring starting at that position that matches the regular
		          expression <var>xyz</var>.</p><p>As with all assertions, evaluation of the assertion does not cause the current position
		          to advance.</p><p>For example, <code nobreak="false">Chapter(?=\s+[1-9])</code> will match <code nobreak="false">"Chapter"</code> only if 
		       followed by a number, with intervening whitespace.</p><p>A parenthesized expression within a lookahead assertion 
		          can capture a substring in the normal way. There are some minor complications, however:</p><ulist><item><p>Substrings captured while evaluating a lookahead assertion are represented
      	          differently in the result of the <function>fn:analyze-string</function>
      	          function, because they can overlap other substrings in arbitrary ways.</p></item><item><p>If an assertion is satisfied, then any substrings that are captured are
	                based on the first evaluation of the assertion that matches; alternative
	                evaluations of the assertion that also match, but which capture different substrings,
	                are not considered.</p></item></ulist><p>A positive lookahead assertion that matches a zero-length string is permitted but pointless,
		          since it will always match, and thus cause the assertion to succeed.</p></div4><div4 id="regex-negative-lookahead-assertion"><head>Negative Lookahead Assertion</head><p>There are two equivalent ways of writing a negative lookahead assertion:</p><p><code nobreak="false">(?!<var>xyz</var>)</code></p><p><code nobreak="false">(*negative_lookahead:<var>xyz</var>)</code></p><p>In both cases, the assertion matches at a particular position in the input string
		          only if there is no substring starting at that position that matches the regular
		          expression <var>xyz</var>.</p><p>As with all assertions, evaluation of the assertion does not cause the current position
		          to advance.</p><p>For example, <code nobreak="false">Chapter(?!\s*[1-9])</code> will match <code nobreak="false">"Chapter"</code> only if 
		       it is not followed by a number, with optional intervening whitespace.</p><p>Any capturing parentheses within a negative lookahead assertion are counted
		       for the purpose of numbering captured groups,
		       but they cannot capture any result because the pattern in the assertion must fail to match.</p><p>A negative lookahead assertion that matches a zero-length string is permitted but pointless,
		          since it will always match, and thus cause the assertion to fail.</p></div4><div4 id="regex-positive-lookbehind"><head>Positive Lookbehind Assertions</head><p>There are two equivalent ways of writing a positive lookbehind assertion:</p><p><code nobreak="false">(?&lt;=<var>xyz</var>)</code></p><p><code nobreak="false">(*positive_lookbehind:<var>xyz</var>)</code></p><p>The second form may be more convenient when the expression appears within an XML-based
		          host language such as XSLT, where the angle bracket would need to be escaped.</p><p>In both cases, the assertion matches at a particular position in the input string
		          only if there is a substring ending at that position that matches the regular
		          expression <var>xyz</var>.</p><p>For efficiency and ease of implementation, the regular expression contained
		       within a lookbehind assertion is constrained. It must consist of one or more
		       alternatives separated by <code nobreak="false">"|"</code>, and each alternative must be fixed-length,
		       consisting only of the following constructs, each of which matches a single character:</p><ulist><item><p><code nobreak="false">NormalChar</code> (for example <code nobreak="false">"A"</code>, <code nobreak="false">"3"</code>)</p></item><item><p><code nobreak="false">SingleCharEsc</code> (for example <code nobreak="false">"\("</code>, <code nobreak="false">"\["</code>)</p></item><item><p><code nobreak="false">charClassEsc</code> (for example <code nobreak="false">"\s"</code>, <code nobreak="false">"\p{Lu}"</code>)</p></item><item><p><code nobreak="false">charClassExpr</code> (for example <code nobreak="false">"[a-z]"</code>)</p></item><item><p><code nobreak="false">WildcardEsc</code> (<code nobreak="false">"."</code>)</p></item></ulist><p>As with all assertions, evaluation of the assertion does not cause the current position
		          to advance.</p><p>Parenthesized expressions cannot appear within lookbehind assertions.</p><p>For example, <code nobreak="false">(?&lt;=\[)[0-9+](?=\])</code> matches a sequence of digits immediately
		       preceded by an opening square bracket and followed by a closing square bracket, without
		       matching the brackets.</p></div4><div4 id="regex-negative-lookbehind"><head>Negative Lookbehind Assertion</head><p>There are two equivalent ways of writing a negative lookbehind assertion:</p><p><code nobreak="false">(?&lt;!<var>xyz</var>)</code></p><p><code nobreak="false">(*negative_lookbehind:<var>xyz</var>)</code></p><p>The second form may be more convenient when the expression appears within an XML-based
		          host language such as XSLT, where the angle bracket would need to be escaped.</p><p>In both cases, the assertion matches at a particular position in the input string
		          only if there is no substring ending at that position that matches the regular
		          expression <var>xyz</var>.</p><p>The regular expression within a negative lookbehind assertion is subject to the
		       same restrictions as for a positive lookbehind assertion: see <specref ref="regex-positive-lookbehind"/>.</p><p>For example, <code nobreak="false">(?&lt;!\$)[0-9]+</code> matches any sequence of digits that
		       is not immediately preceded by a dollar sign.</p></div4></div3></div2><div2 id="flags"><head>Flags</head><changes><change issue="999" PR="1022" date="2024-02-20">
                     Regular expressions can include comments (starting and ending with <code nobreak="false">#</code>)
                     if the <code nobreak="false">c</code> flag is set.
                  </change></changes><p>All these functions provide an optional parameter, <code nobreak="false">$flags</code>,
                    to set options for the interpretation of the regular expression. The
                    parameter accepts a <code nobreak="false">xs:string</code>, in which individual letters
                    are used to set options. The presence of a letter within the string
                    indicates that the option is on; its absence indicates that the option
                    is off. Letters may appear in any order and may be repeated. They are case-sensitive. If there
                    are characters present that are not defined here as flags, then a dynamic error
                    is raised <errorref class="RX" code="0001"/>.</p><p>The following options are defined:</p><ulist><item><p><code nobreak="false">s</code>: If present, the match operates in “dot-all”
                        mode. (Perl calls this the single-line mode.) If the
                        <code nobreak="false">s</code> flag is not specified, the meta-character
                        <code nobreak="false">.</code> matches any character except a newline
                        (<code nobreak="false">#x0A</code>) or carriage return (<code nobreak="false">#x0D</code>) 
                        character. In dot-all mode, the
                        meta-character <code nobreak="false">.</code> matches any character whatsoever.
                        Suppose the input contains the strings <code nobreak="false">"hello"</code> and
                        <code nobreak="false">"world"</code> on two lines.
                        This will not be matched by the regular expression
                        <code nobreak="false">"hello.*world"</code> unless dot-all mode is enabled.</p></item><item><p>
                           <code nobreak="false">m</code>: If present, the match operates in multi-line
			            mode. By default, the meta-character <code nobreak="false">^</code> matches the
			            start of the entire string, while $ matches the end of the
			            entire string. In multi-line mode, <code nobreak="false">^</code> matches the
			            start of any line (that is, the start of the entire string, and
			            the position immediately after a newline character
						other than a newline
			            that appears as the last character in the string), while
			            <code nobreak="false">$</code> matches the end of any line 
						(that is, the position immediately
			            before a newline character, and the end of the entire string if there is no
			            newline character at the end of the string).
			            Newline here means the character <code nobreak="false">#x0A</code> only.</p></item><item><p><code nobreak="false">i</code>: If present, the match operates in
                        case-insensitive mode. The detailed rules are as follows. 
                        In these
                        rules, a character C2 is considered to be a <emph>case-variant</emph> of 
                        another character C1 if the following XPath expression returns 
                        <code nobreak="false">true</code> when the two characters
                           are considered as strings of length one, and the 
                           <termref def="dt-codepoint-collation">Unicode codepoint collation</termref> is used:</p><p>
                           <code nobreak="false">fn:lower-case(C1) eq fn:lower-case(C2) or
                        fn:upper-case(C1) eq fn:upper-case(C2)</code>
                        </p><p>
                                     Note that the case-variants of a character under this definition 
                                     are always single characters.</p><olist><item><p>
                                    When a normal character (<code nobreak="false">Char</code>) is used as an atom, 
                                    it represents 
                                    the set containing that character and all its case-variants. 
                                    For example, the regular expression <code nobreak="false">"z"</code> will
                                    match both <code nobreak="false">"z"</code> and <code nobreak="false">"Z"</code>.</p></item><item><p>
                                    A character range (productions <code nobreak="false">charRange</code> and <code nobreak="false">singleChar</code>
                                    in the XSD 1.1 grammar) represents the set 
                                    containing all the characters that it would match in the absence 
                                    of the <code nobreak="false">i</code> flag, together with their case-variants. 
                                    For example, 
                                    the regular expression <code nobreak="false">"[A-Z]"</code> will match all
                                    the letters <code nobreak="false">A</code> to <code nobreak="false">Z</code> and all the letters
                                    <code nobreak="false">a</code> to <code nobreak="false">z</code>. It will also match 
                                    certain other characters such as <code nobreak="false">#x212A</code> (KELVIN SIGN), since 
                                    <code nobreak="false">fn:lower-case("#x212A")</code> is <code nobreak="false">k</code>.</p><p>
                                    This rule applies also to a character range used in a character 
                                    class subtraction (<code nobreak="false">charClassSub</code>): thus [A-Z-[IO]] will match 
                                    characters such as <code nobreak="false">A</code>, <code nobreak="false">B</code>, <code nobreak="false">a</code>, and <code nobreak="false">b</code>, but will not match 
                                    <code nobreak="false">I</code>, <code nobreak="false">O</code>, <code nobreak="false">i</code>, or <code nobreak="false">o</code>.</p><p>
                                    The rule also applies to a character range used as part of a 
                                    negative character group: thus <code nobreak="false">"[^Q]"</code> will match every character 
                                    except <code nobreak="false">Q</code> and <code nobreak="false">q</code> (these being the only case-variants of <code nobreak="false">Q</code> in 
                                    Unicode).</p></item><item><p>
                                    A back-reference is compared using case-blind comparison: 
                                    that is, each character must either be the same as the 
                                    corresponding character of the previously matched string, or must 
                                    be a case-variant of that character. For example, the strings 
                                    <code nobreak="false">"Mum"</code>, <code nobreak="false">"mom"</code>, <code nobreak="false">"Dad"</code>,
                                    and <code nobreak="false">"DUD"</code> all match the regular
                                    expression <code nobreak="false">"([md])[aeiou]\1"</code> when the <code nobreak="false">i</code> flag is used.</p></item><item><p>
                                    All other constructs are unaffected by the <code nobreak="false">i</code> flag. 
                                    For example, 
                                    <code nobreak="false">"\p{Lu}"</code> continues to match upper-case letters only.</p></item></olist></item><item><p><code nobreak="false">x</code>: If present, whitespace characters 
                                    (that is, <char>U+0009</char>, <char>U+000A</char>, <char>U+000D</char> and <char>U+000D</char>)
                                    in the regular expression are removed prior to matching with one exception:  
                                    whitespace characters within character class expressions 
                                    (<code nobreak="false">charClassExpr</code>) are not removed. This flag can be used, 
                                    for example, to break up long regular expressions into readable lines.</p><p> Examples:</p><p> 
                           <code nobreak="false">fn:matches("helloworld", "hello world", "x")</code> returns <code nobreak="false">true()</code>
                        </p><p> 
                           <code nobreak="false">fn:matches("helloworld", "hello[ ]world", "x")</code> returns <code nobreak="false">false()</code>
                        </p><p> 
                           <code nobreak="false">fn:matches("hello world", "hello\ sworld", "x")</code> returns <code nobreak="false">true()</code>
                        </p><p> 
                           <code nobreak="false">fn:matches("hello world", "hello world", "x")</code> returns <code nobreak="false">false()</code>
                        </p><note><p>Whitespace is treated as a lexical construct to be removed before the
                        regular expression is parsed; it is therefore not explicit in the regular expression grammar.</p></note></item><item><p><code nobreak="false">q</code>: if present, all characters in the regular expression
                     are treated as representing themselves, not as metacharacters. In effect, every
                     character that would normally have a special meaning in a regular expression is implicitly escaped
                     by preceding it with a backslash.</p><p>Furthermore, when this flag is present, the characters <code nobreak="false">$</code> and
                         <code nobreak="false">\</code> have no special significance when used in the replacement string
                         supplied to the <function>fn:replace</function> function.</p><p>This flag can be used in conjunction with the <code nobreak="false">i</code> flag. If it is used
                           together with the <code nobreak="false">m</code>, <code nobreak="false">s</code>, <code nobreak="false">x</code>, 
                           <phrase diff="add" at="issue999">or <code nobreak="false">c</code></phrase> flag, that flag
                           has no effect.</p><p>Examples:</p><p><code nobreak="false">tokenize("12.3.5.6", ".", "q")</code> returns <code nobreak="false">("12", "3", "5", "6")</code></p><p><code nobreak="false">replace("a\b\c", "\", "\\", "q")</code> returns <code nobreak="false">"a\\b\\c"</code></p><p><code nobreak="false">replace("a/b/c", "/", "$", "q")</code> returns <code nobreak="false">"a$b$c"</code></p><p><code nobreak="false">matches("abcd", ".*", "q")</code> returns <code nobreak="false">false()</code></p><p><code nobreak="false">matches("Mr. B. Obama", "B. OBAMA", "iq")</code> returns <code nobreak="false">true()</code></p></item><item diff="add" at="issue999"><p><code nobreak="false">c</code>: if present, comments are enabled
                        in the regular expression. This flag has no effect if the <code nobreak="false">q</code> flag is
                        present. A comment is recognized by the presence of a <code nobreak="false">#</code> character that
                        is not escaped by a backslash or contained in a character class expression
                        (<code nobreak="false">charClassExpr</code>), and it is terminated by the following <code nobreak="false">#</code>
                        character or by the end of the regular expression string.</p><p>For example:</p><p><code nobreak="false">replace("03/24/2025", "(..#month#)/(..#day#)/(....#year#)", "$3-$1-$2", "c")</code></p><note><p>Comments are treated as a lexical construct to be removed before the
                           regular expression is parsed; they are therefore not explicit in the regular 
                           expression grammar.</p></note></item></ulist></div2><div2 id="regex-functions"><head>Functions using regular expressions</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:matches</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the supplied string matches a given regular expression.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:replace</code></td><td rowspan="1" colspan="1">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.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:tokenize</code></td><td rowspan="1" colspan="1">Returns 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.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:analyze-string</code></td><td rowspan="1" colspan="1">Analyzes 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.</td></tr></tbody></table><div3 id="func-matches"><head>fn:matches</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the supplied string matches a given regular expression.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="matches" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="flags" type="xs:string?" default="&#34;&#34;" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, it is interpreted as the zero-length
            string.</p><p>Flags are defined in <specref ref="flags"/>.</p><p>The function returns <code nobreak="false">true</code> if the set of <termref def="dt-disjoint-matching-segments"/> obtained
            by matching <code nobreak="false">$value</code> against the regular expression <code nobreak="false">$pattern</code>,
            with the associated <code nobreak="false">$flags</code>, is non-empty. Otherwise, the function returns <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RX" code="0002"/> if 
               <code nobreak="false">$pattern</code> is invalid according to the rules described in <specref ref="regex-syntax"/>. </p><p>A dynamic error is raised <errorref class="RX" code="0001"/> if 
               <code nobreak="false">$flags</code> is invalid according to the rules described in <specref ref="flags"/>. </p></def></gitem><gitem><label>Notes</label><def><note><p>Unless the metacharacters <code nobreak="false">^</code> and <code nobreak="false">$</code> are used as anchors, the
            string is considered to match the pattern if any substring matches the pattern. But if
            anchors are used, the anchors must match the start/end of the string (in string mode),
            or the start/end of a line (in multi-line mode). </p><p>This is different from the behavior of patterns in <bibref ref="xmlschema-2"/>, where
            regular expressions are <emph>implicitly</emph> anchored.</p><p>Regular expression matching is defined on the basis of Unicode codepoints; it takes no
            account of collations.</p><p>It is valid for the regular expression to match a zero-length segment of <code nobreak="false">$value</code>.
         For example, the result of the expression <code nobreak="false">matches($s, "")</code> is always true, regardless
         of the value of <code nobreak="false">$s</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $poem := &lt;poem author="Wilhelm Busch"&gt;
Kaum hat dies der Hahn gesehen,
Fängt er auch schon an zu krähen:
Kikeriki! Kikikerikih!!
Tak, tak, tak! - da kommen sie.
&lt;/poem&gt;</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">matches("abracadabra", "bra")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">matches("abracadabra", "^a.*a$")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">matches("abracadabra", "^bra")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">matches($poem, "Kaum.*krähen")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">matches($poem, "Kaum.*krähen", "s")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">matches($poem, "^Kaum.*gesehen,$", "m")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">matches($poem, "^Kaum.*gesehen,$")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">matches($poem, "kiki", "i")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-replace"><head>fn:replace</head><changes><change issue="1876" PR="1897" date="2025-04-08">The <code nobreak="false">$replacement</code> argument can now be a function
            that computes the replacement strings.</change><change issue="1911" PR="1913" date="2025-04-08">It is now permitted for the regular expression to match a zero-length string.</change></changes><glist><gitem><label>Summary</label><def><p>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.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="replace" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="replacement" type="(xs:string | fn(xs:untypedAtomic, xs:untypedAtomic*) as item()?)?" default="&#34;&#34;" note="default-on-empty"/><arg name="flags" type="xs:string?" default="&#34;&#34;" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If the <code nobreak="false">$flags</code> argument is omitted or if it is the empty sequence,
            the effect is the same as setting <code nobreak="false">$flags</code> to a zero-length string.
            Flags are defined in <specref ref="flags"/>.</p><p>The string <code nobreak="false">$value</code> is matched against the regular expression <code nobreak="false">$pattern</code>,
            using the supplied <code nobreak="false">$flags</code>, to obtain a set of <termref def="dt-disjoint-matching-segments"/>.
            A replacement string <var>R</var> for each 
            of these segments (say <var>M</var>) is determined by the value of the
            <code nobreak="false">$replacement</code> argument, by applying the first
         of the following rules that applies:</p><ulist><item><p>If <code nobreak="false">$replacement</code> is a function item <var>F</var>, then
               <var>R</var> is obtained by calling <var>F</var>, and then applying the
               function <function>fn:string</function> to the result.</p><p>The first argument to <var>F</var> is the string to be replaced,
                  provided as <code nobreak="false">xs:untypedAtomic</code>.</p><p>The second argument to <var>F</var> provides the captured
                  groups as an <code nobreak="false">xs:untypedAtomic</code> sequence.
                  The <code nobreak="false">Nth</code> item in this sequence is the string value of the segment captured by 
                  the <code nobreak="false">Nth</code> capturing subexpression. If the
                  <code nobreak="false">Nth</code> capturing subexpression was not matched, the <code nobreak="false">Nth</code> item
                  will be the zero-length string.</p><p>Note that the rules for function coercion mean that the function actually
                  supplied for <var>F</var> may be an arity-1 function: the
                  second argument does not need to be declared if it is not used.</p></item><item><p>If <code nobreak="false">$replacement</code> is a string and the 
               <code nobreak="false">q</code> flag is present, <var>R</var> is the value
            of <code nobreak="false">$replacement</code>.</p></item><item><p>Otherwise, the value of <code nobreak="false">$replacement</code> is processed as follows.</p><p>Within the supplied <code nobreak="false">$replacement</code> string, a variable marker <code nobreak="false">$<var>N</var></code> (where 
               <var>N</var> is an unsigned integer) may
            be used to refer to the <var>N</var>th captured group associated with <var>M</var>.
               The replacement string <var>R</var> is obtained by replacing each of these variable markers
            with the string value of the relevant captured group.
               The variable marker <code nobreak="false">$0</code> refers to the substring captured by the regular expression as a
            whole.</p><p>A literal <code nobreak="false">$</code> character within the
            replacement string must be written as <code nobreak="false">\$</code>, and a literal <code nobreak="false">\</code>
            character must be written as <code nobreak="false">\\</code>.</p><p>More specifically, the rules are as follows, where <var>S</var> is the number of
            capturing subexpressions in the regular expression, and <var>N</var> is the
            decimal number formed by taking all the digits that consecutively follow the
               <code nobreak="false">$</code> character in <code nobreak="false">$replacement</code>:</p><olist><item><p>If <var>N</var>=<code nobreak="false">0</code>, then the variable is replaced by the string value of <var>M</var>.</p></item><item><p>If <code nobreak="false">1</code>&lt;=<var>N</var>&lt;=<var>S</var>, then the variable marker is
                  replaced by the string value of the <var>N</var>th captured group associated
                  with <var>M</var>. If the
                     <var>N</var>th parenthesized sub-expression was not matched, then the
                  variable marker is replaced by the zero-length string.</p></item><item><p>If <var>S</var>&lt;<var>N</var>&lt;=<code nobreak="false">9</code>, then the variable marker is
                  replaced by the zero-length string.</p></item><item><p>Otherwise (if <var>N</var>&gt;<var>S</var> and
                     <var>N</var>&gt;<code nobreak="false">9</code>), the last digit of <var>N</var> is taken to
                  be a literal character to be included “as is” in the replacement string, and the
                  rules are reapplied using the number <var>N</var> formed by stripping off this
                  last digit.</p><p>For example, if the replacement string is 
               <code nobreak="false">"$23"</code>
             and there are 5 substrings, the result contains the value of the substring that
            matches the second capturing subexpression, followed by the digit 
               <code nobreak="false">3</code>.</p></item></olist></item></ulist><p>The function returns the <code nobreak="false">xs:string</code> that is obtained by replacing each
            of the <termref def="dt-disjoint-matching-segments"/> of <code nobreak="false">$value</code> with 
            the corresponding value of <var>R</var>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RX" code="0002"/> if the value of
               <code nobreak="false">$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>. </p><p>A dynamic error is raised <errorref class="RX" code="0001"/> if the value of
               <code nobreak="false">$flags</code> is invalid according to the rules described in section <specref ref="flags"/>. </p><!--<p>A dynamic error is raised <errorref class="RX" code="0003"
               /> if the pattern matches a
            zero-length string, that is, if the expression <code>fn:matches("", $pattern,
               $flags)</code> returns <code>true</code>. It is not an error, however, if a captured
            substring is zero-length.</p>--><p>In the absence of the <code nobreak="false">q</code> flag,
            a dynamic error is raised <errorref class="RX" code="0004"/> if the value of
               <code nobreak="false">$replacement</code> contains a dollar sign (<code nobreak="false">$</code>) character that is not
            immediately followed by a digit <code nobreak="false">0-9</code> and not immediately preceded by a
            backslash (<code nobreak="false">\</code>).</p><p>In the absence of the <code nobreak="false">q</code> flag,
            a dynamic error is raised <errorref class="RX" code="0004"/> if the value of
               <code nobreak="false">$replacement</code> contains a backslash (<code nobreak="false">\</code>) character that is not part of a
               <code nobreak="false">\\</code> pair, unless it is immediately followed by a dollar sign (<code nobreak="false">$</code>)
            character.</p><p>A dynamic error is raised <errorref class="RX" code="0005"/> if both the <code nobreak="false">$replacement</code> 
            and <code nobreak="false">$action</code> arguments are supplied, and neither is the empty sequence.</p></def></gitem><gitem><label>Notes</label><def><note><p>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.</p><p>If two overlapping substrings of <code nobreak="false">$value</code> both match the
            <code nobreak="false">$pattern</code>, then only the first one (that is, the one whose first <termref def="character">character</termref> comes first in the <code nobreak="false">$value</code> string) is
            replaced.</p><p> If two alternatives within the pattern both match at the same position in the
               <code nobreak="false">$input</code>, then the match that is chosen is the one matched by the first
            alternative. For example:</p><eg xml:space="preserve"> replace("abcd", "(ab)|(a)", "[1=$1][2=$2]") returns "[1=ab][2=]cd"</eg><p>The rules for <termref def="dt-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 <code nobreak="false">.*</code>
         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.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("abracadabra", "bra", "*")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a*cada*"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("abracadabra", "a.*a", "*")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"*"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("abracadabra", "a.*?a", "*")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"*c*bra"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("abracadabra", "a", "")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"brcdbr"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("abracadabra", "a(.)", "a$1$1")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"abbraccaddabbra"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("AAAA", "A+", "b")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("AAAA", "A+?", "b")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"bbbb"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("In the beginning was the Word", "\b", "|")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"|In| |the| |beginning| |was| |the| |Word|"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("abcd!", "[a-z](?=.*(.)$)", "$0$1")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a!b!c!d!!"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">replace("darted", "^(.*?)d(.*)$", "$1c$2")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"carted"</code></p><p><emph>(Only the first <code nobreak="false">d</code> is replaced.)</emph></p></td></tr><tr class="testdiv" diff="add" at="A"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">replace("abracadabra", "bra", upper-case#1)</eg></td></tr><tr diff="add" at="A"><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"aBRAcadaBRA"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">replace("Chapter 9", "[0-9]+", fn { . + 1 })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Chapter 10"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">replace(
  "LHR to LAX",
  "\b[A-Z]{3}\b",
  { 'LAX': 'Los Angeles', 'LHR': 'London' }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"London to Los Angeles"</eg></td></tr><tr class="testdiv" diff="add" at="A"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">replace(
  "57°43′30″",
  "([0-9]+)°([0-9]+)′([0-9]+)″",
  fn($s, $groups) {
    string($groups[1] + $groups[2] ÷ 60 + $groups[3] ÷ 3600) || '°'
  }
)</eg></td></tr><tr diff="add" at="A"><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"57.725°"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-tokenize"><head>fn:tokenize</head><changes><change issue="895" PR="901" date="2023-12-16">The second argument can now be the empty sequence.</change><change issue="1911" PR="1913" date="2025-04-08">It is now permitted for the regular expression to match a zero-length string.</change></changes><glist><gitem><label>Summary</label><def><p>Returns 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.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="tokenize" return-type="xs:string*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="pattern" type="xs:string?" default="()"/><arg name="flags" type="xs:string?" default="&#34;&#34;" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p diff="add" at="2023-01-17">The following rules apply when the <code nobreak="false">$pattern</code>
            argument is the empty sequence:</p><ulist><item><p>The function splits the supplied string at whitespace boundaries.</p></item><item><p>More specifically, calling <code nobreak="false">fn:tokenize($value)</code> <phrase diff="add" at="2023-01-17">or <code nobreak="false">fn:tokenize($value, ())</code></phrase>
               is equivalent to calling <code nobreak="false">fn:tokenize(fn:normalize-space($value), ' '))</code> where the second argument
               is a single space character (x20).</p></item><item><p>The <code nobreak="false">$flags</code> argument is ignored.</p></item></ulist><p>The following rules apply when the <code nobreak="false">$pattern</code> argument is supplied as a single string:</p><ulist><item><p>Flags are defined in <specref ref="flags"/>.</p></item><item><p>If <code nobreak="false">$value</code> is the empty sequence, or if <code nobreak="false">$value</code> is the
               zero-length string, the function returns the empty sequence.</p></item><item><p>The function returns a sequence of strings formed by breaking the <code nobreak="false">$value</code>
                  string into a sequence of strings, treating any substring that matches
                  <code nobreak="false">$pattern</code> as a separator. The separators themselves are not returned.</p></item><item><p>More specifically:</p><ulist><item><p>Let <var>M0</var> be the sequence of <termref def="dt-disjoint-matching-segments"/>
            that results from matching <code nobreak="false">$value</code> against <code nobreak="false">$pattern</code> in the presence
            of <code nobreak="false">$flags</code>.</p></item><item><p>Unless the first segment in <var>M0</var> is zero-length and starts at the first <termref def="dt-character-position"/>
                  of <code nobreak="false">$value</code>, prepend a zero-length segment that starts at the start of <code nobreak="false">$value</code>:
                  call the result <var>M1</var>.</p></item><item><p>Unless the last segment in <var>M1</var> is zero-length and starts at the last <termref def="dt-character-position"/>
                  of <code nobreak="false">$value</code> (that is, the character position after the last character), append a zero-length 
                     segment that starts at the last character position of <code nobreak="false">$value</code>. Call the result <var>M2</var>.</p></item><item><p>For each pair of adjacent segments in <var>M2</var> (say, <var>S/n</var> and <var>S/n+1</var>),
                  construct a string (possibly zero-length) that is the substring of <code nobreak="false">$value</code> containing all characters 
                  that follow <var>S/n</var> and that precede <var>S/n+1</var>. Return this sequence of strings, in order.</p></item></ulist></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RX" code="0002"/> if the value of
               <code nobreak="false">$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p>A dynamic error is raised <errorref class="RX" code="0001"/> if the value of
               <code nobreak="false">$flags</code> is invalid according to the rules described in section <specref ref="flags"/>.</p><!--<p>A dynamic error is raised <errorref class="RX" code="0003"
               /> if the supplied
               <code>$pattern</code> matches a zero-length string, that is, if <code>fn:matches("",
               $pattern, $flags)</code> returns <code>true</code>. </p>--></def></gitem><gitem><label>Notes</label><def><note><p>If the input string is not zero length, and no separators are found in
            the input string, the result of the function is a single string identical to the input
            string.</p><p>For the one-argument form of the function:</p><ulist><item><p>The function has a similar effect to
               the two-argument form with <code nobreak="false">\s+</code> as the separator pattern, except that the one-argument
               form strips leading and trailing whitespace, whereas the two-argument form delivers an extra
               zero-length token if leading or trailing whitespace is present.</p></item><item><p>The separator used is any sequence
            of tab (<char>U+0009</char>), newline (<char>U+000A</char>), carriage return
            (<char>U+000D</char>) or space (<char>U+0020</char>) characters. This is the same as the
               separator recognized by list-valued attributes as defined in XSD.
               It is not the same as the separator recognized by list-valued attributes in HTML5,
               which also treats form-feed (<char>U+000C</char>) as whitespace. If it is necessary
               to treat form-feed as a separator, an explicit separator pattern should be used.</p></item></ulist><p>For the two-argument form of the function:</p><ulist><item><p>The function returns no information about the separators that were found
         in the string. If this information is required, the <function>fn:analyze-string</function> function
         can be used instead. Alternatively, zero-width assertions can be used to identify separators.
         For example, using the regular expression <code nobreak="false">(?&lt;=,)</code> will start a new token after every comma,
         including the comma as part of the previous token.</p></item><item><p>If a separator occurs at the start of <code nobreak="false">$value</code>, and is not zero-length, the result
                  sequence will start with a zero-length string. Similarly, zero-length strings will also occur in
                  the result sequence if a non-zero-length separator occurs at the end of <code nobreak="false">$value</code>,
                  or if two adjacent substrings match the supplied <code nobreak="false">$pattern</code>.</p></item><item><p>If two alternatives within the supplied <code nobreak="false">$pattern</code> both match at the same
                  position in the <code nobreak="false">$value</code> string, then the match that is chosen is the first.
                  For example:</p><eg xml:space="preserve"> tokenize("abracadabra", "(ab)|(a)") returns ("", "r", "c", "d", "r", "")</eg></item><item><p>The pattern may match zero-length segments of the input string. For example, the 
                 expression <code nobreak="false">tokenize("Do not eat", "\b")</code> returns the sequence 
               <code nobreak="false">"Do", " ", "not", " ", "eat"</code>.</p></item><item><p>A string may be split into individual characters (producing the same effect as the
               <function>fn:characters</function> function) by using the empty regular expression 
               (for example, <code nobreak="false">tokenize("xyz", "")</code>,
               or any other regular expression such as <code nobreak="false">.??</code> that matches every zero-length string, regardless
               of position.</p><p>Unlike the <code nobreak="false">split</code> method in some other popular languages, however,
                  not every regular expression that matches a zero-length string produces this
                  behavior: for example the regular expression <code nobreak="false">\b</code> splits the string
                  before and after every word.</p></item></ulist></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">tokenize(" red green blue ")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"red", "green", "blue"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">tokenize("The cat sat on the mat", "\s+")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"The", "cat", "sat", "on", "the", "mat"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">tokenize(" red green blue ", "\s+")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"", "red", "green", "blue", ""</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">tokenize("1, 15, 24, 50", ",\s*")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1", "15", "24", "50"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">tokenize("1,15,,24,50,", ",")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"1", "15", "", "24", "50", ""</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:tokenize("the end", "\b")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"the", " ", "end"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:tokenize("California", "")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"C", "a", "l", "i", "f", "o", "r", "n", "i", "a"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">tokenize(
  "Some unparsed &lt;br&gt; HTML &lt;BR&gt; text",
  "\s*&lt;br&gt;\s*", "i"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Some unparsed", "HTML", "text"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-analyze-string"><head>fn:analyze-string</head><changes><change issue="998" PR="1856" date="2025-03-18">The output of the function is extended to allow the represention of
               captured groups found within lookahead assertions.</change><change issue="1911" PR="1913" date="2025-04-08">It is now permitted for the regular expression to match a zero-length string.</change></changes><glist><gitem><label>Summary</label><def><p>Analyzes 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.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="analyze-string" return-type="element(fn:analyze-string-result)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="pattern" type="xs:string"/><arg name="flags" type="xs:string?" default="&#34;&#34;" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Flags are defined in <specref ref="flags"/>.</p><p>If <code nobreak="false">$value</code> is the empty sequence, the function behaves as if
            <code nobreak="false">$value</code> were the zero-length string.</p><p>The function returns an element node whose local name is
               <code nobreak="false">analyze-string-result</code>. This element and all its descendant elements have
            the namespace URI <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>. The namespace
            prefix is <termref def="implementation-dependent">implementation-dependent</termref>. The children of this element are a
            sequence of <code nobreak="false">fn:match</code> and <code nobreak="false">fn:non-match</code> elements. This sequence
            is formed by breaking the <code nobreak="false">$value</code> string into a sequence of strings,
            returning any substring that matches <code nobreak="false">$pattern</code> as the content of an
               <code nobreak="false">fn:match</code> element, and any intervening substring as the content of an
               <code nobreak="false">fn:non-match</code> element.</p><p>More specifically, the function starts by matching the regular expression against the string,
            using the supplied <code nobreak="false">$flags</code>, to obtain the <termref def="dt-disjoint-matching-segments"/>.
            For each such segment it constructs an <code role="element-name" nobreak="false">fn:match</code> child, whose string value is
            the string value of the segment. Before, between, or after these <code role="element-name" nobreak="false">fn:match</code>
            elements, as required to ensure that the string value of the <code role="element-name" nobreak="false">fn:analyze-string-result</code>
            element is the same as <code nobreak="false">$value</code>, it inserts <code role="element-name" nobreak="false">fn:non-match</code> elements.
            The content of an <code role="element-name" nobreak="false">fn:non-match</code> element is always a single (non-empty) text node,
            and two <code role="element-name" nobreak="false">fn:non-match</code> elements never appear as adjacent siblings.</p><p>The captured groups for each <termref def="dt-disjoint-matching-segments">disjoint matching segment</termref>
            are represented using <code role="element-name" nobreak="false">fn:group</code> or <code role="element-name" nobreak="false">fn:lookahead-group</code>
            children of the corresponding <code role="element-name" nobreak="false">fn:match</code> element. Groups captured by a subexpression within
         a lookahead assertion are referred to as lookahead groups; those not within a lookahead
         assertion are called ordinary groups.</p><p>The content of an <code role="element-name" nobreak="false">fn:match</code> element is in general:</p><ulist><item><p>A sequence of text nodes and <code role="element-name" nobreak="false">fn:group</code> element children,
            whose string-values when concatenated comprise the string value of the matching segment,
            followed by</p></item><item><p>A sequence of zero or more <code role="element-name" nobreak="false">fn:lookahead-group</code> elements, 
            representing the lookahead groups</p></item></ulist><p>The string value of an <code role="element-name" nobreak="false">fn:match</code> element may be empty.</p><p>An <code role="element-name" nobreak="false">fn:group</code> element
            with a <code nobreak="false">nr</code> attribute having the integer value <var>N</var> identifies 
            the substring captured by an ordinary group, specifically the string value of the <var>Nth</var> captured group. 
            For each ordinary capturing subexpression there will be at most one corresponding
               <code role="element-name" nobreak="false">fn:group</code> element in each <code nobreak="false">fn:match</code> element in the
            result.</p><p>By contrast, lookahead groups are represented by <code role="element-name" nobreak="false">fn:lookahead-group</code> elements,
         which (if they appear at all) must follow all text node and <code role="element-name" nobreak="false">fn:group</code> element children
         of the <code role="element-name" nobreak="false">fn:match</code> element. These groups may overlap the matching and non-matching substrings, and
         indeed may overlap each other. They must appear in ascending numerical order of group number.
         The attributes of the <code role="element-name" nobreak="false">fn:lookahead-group</code> element are as follows:</p><ulist><item><p><code nobreak="false">nr</code>: the group number, based on the position of the capturing subexpression
            that captured the group;</p></item><item><p><code nobreak="false">value</code>: the string value of the segment that was captured;</p></item><item><p><code nobreak="false">position</code>: the one-based start position of the segment within the input string.</p></item></ulist><p>If the function is called twice with the same arguments, it is <termref def="implementation-dependent">implementation-dependent</termref> whether the two calls return the same element node
            or distinct (but deep equal) element nodes. In this respect it is <termref def="dt-nondeterministic">nondeterministic with respect to node identity</termref>.</p><p>The base URI of the element nodes in the result is <termref def="implementation-dependent">implementation-dependent</termref>.</p><p>A schema is defined for the structure of the returned element: see <specref ref="schema-for-analyze-string"/>.</p><p>The result of the function will always be such that validation against this schema would succeed.
         However, it is <termref def="implementation-defined">implementation-defined</termref> whether the result is typed or untyped,
         that is, whether the elements and attributes in the returned tree have type annotations that reflect
         the result of validating against this schema.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RX" code="0002"/> if the value of
               <code nobreak="false">$pattern</code> is invalid according to the rules described in section <specref ref="regex-syntax"/>.</p><p>A dynamic error is raised <errorref class="RX" code="0001"/> if the value of
               <code nobreak="false">$flags</code> is invalid according to the rules described in section <specref ref="flags"/>.</p><!--<p>A dynamic error is raised <errorref class="RX" code="0003"
               /> if the supplied
               <code>$pattern</code> matches a zero-length string, that is, if <code>fn:matches("",
               $pattern, $flags)</code> returns <code>true</code>.</p>--></def></gitem><gitem><label>Notes</label><def><note><p>It is <rfc2119>recommended</rfc2119> that a processor that implements schema awareness should return typed nodes.
            The concept of “schema awareness”, however, is a matter for host languages to define and is outside
            the scope of the function library specification.</p><p>The declarations and definitions in the schema are not automatically available in
            the static context of the <function>fn:analyze-string</function> call (or of any other
            expression). The contents of the static context are host-language defined, and in some
            host languages are implementation-defined.</p><p>The schema defines the outermost element, <code nobreak="false">analyze-string-result</code>, in such
         a way that mixed content is permitted. In fact the element will only have element nodes (<code nobreak="false">match</code>
         and <code nobreak="false">non-match</code>) as its children, never text nodes. Although this might have originally been an
            oversight, defining the <code nobreak="false">analyze-string-result</code> element with <code nobreak="false">mixed="true"</code> allows it
         to be atomized, which is potentially useful (the atomized value will be the original input string),
         and the capability has therefore been retained for compatibility with the 3.0 version of this
         specification.</p><p>The rules for <termref def="dt-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 <code nobreak="false">.*</code>
         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.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>In the following examples, the result document is shown in serialized form, with
               whitespace between the element nodes. This whitespace is not actually present in the
               result.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">analyze-string("The cat sat on the mat.", "\w+")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;match&gt;The&lt;/match&gt;
  &lt;non-match&gt; &lt;/non-match&gt;
  &lt;match&gt;cat&lt;/match&gt;
  &lt;non-match&gt; &lt;/non-match&gt;
  &lt;match&gt;sat&lt;/match&gt;
  &lt;non-match&gt; &lt;/non-match&gt;
  &lt;match&gt;on&lt;/match&gt;
  &lt;non-match&gt; &lt;/non-match&gt;
  &lt;match&gt;the&lt;/match&gt;
  &lt;non-match&gt; &lt;/non-match&gt;
  &lt;match&gt;mat&lt;/match&gt;
  &lt;non-match&gt;.&lt;/non-match&gt;
&lt;/analyze-string-result&gt;</eg><p>(with whitespace added for legibility)</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">analyze-string("08-12-03", "^(\d+)\-(\d+)\-(\d+)$")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;match&gt;
    &lt;group nr="1"&gt;08&lt;/group&gt;-&lt;group nr="2"&gt;12&lt;/group&gt;-&lt;group nr="3"&gt;03&lt;/group&gt;
  &lt;/match&gt;
&lt;/analyze-string-result&gt;</eg><p>(with whitespace added for legibility)</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">analyze-string("A1,C15,,D24, X50,", "([A-Z])([0-9]+)")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;match&gt;
    &lt;group nr="1"&gt;A&lt;/group&gt;
    &lt;group nr="2"&gt;1&lt;/group&gt;
  &lt;/match&gt;
  &lt;non-match&gt;,&lt;/non-match&gt;
  &lt;match&gt;
    &lt;group nr="1"&gt;C&lt;/group&gt;
    &lt;group nr="2"&gt;15&lt;/group&gt;
  &lt;/match&gt;
  &lt;non-match&gt;,,&lt;/non-match&gt;
  &lt;match&gt;
    &lt;group nr="1"&gt;D&lt;/group&gt;
    &lt;group nr="2"&gt;24&lt;/group&gt;
  &lt;/match&gt;
  &lt;non-match&gt;, &lt;/non-match&gt;
  &lt;match&gt;
    &lt;group nr="1"&gt;X&lt;/group&gt;
    &lt;group nr="2"&gt;50&lt;/group&gt;
  &lt;/match&gt;
  &lt;non-match&gt;,&lt;/non-match&gt;
&lt;/analyze-string-result&gt;</eg><p>(with whitespace added for legibility)</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">analyze-string("Chapter 5", "(Chapter|Appendix)(?=\s+([0-9]+))")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;match&gt;
    &lt;group nr="1"&gt;Chapter&lt;/group&gt;
    &lt;lookahead-group nr="2" value="5" position="9"/&gt;
  &lt;/match&gt;
  &lt;non-match&gt; 5&lt;/non-match&gt;  
&lt;/analyze-string-result&gt;</eg><p>(with whitespace added for legibility)</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">analyze-string("There we go", "\b(?=(\w+))")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;analyze-string-result xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;match&gt;&lt;lookahead-group nr="1" value="There" position="1"/&gt;&lt;/match&gt;
  &lt;non-match&gt;There &lt;/non-match&gt;
  &lt;match&gt;&lt;lookahead-group nr="1" value="we" position="7"/&gt;&lt;/match&gt;
  &lt;non-match&gt;we &lt;/non-match&gt;
  &lt;match&gt;&lt;lookahead-group nr="1" value="go" position="10"/&gt;&lt;/match&gt;
  &lt;non-match&gt;go&lt;/non-match&gt;
&lt;/analyze-string-result&gt;</eg><p>(with whitespace added for legibility)</p></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="anyURI-functions"><head>Processing URIs</head><p>This section specifies functions that manipulate URI values, either as instances
            of <code nobreak="false">xs:anyURI</code> or as strings.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:decode-from-uri</code></td><td rowspan="1" colspan="1">Decodes URI-escaped characters in a string.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:encode-for-uri</code></td><td rowspan="1" colspan="1">Encodes reserved characters in a string that is intended to be used in the path segment
            of a URI.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:escape-html-uri</code></td><td rowspan="1" colspan="1">Escapes a URI in the same way that HTML user agents handle attribute values expected to
            contain URIs.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:iri-to-uri</code></td><td rowspan="1" colspan="1">Converts a string containing an IRI into a URI according to the rules of <bibref ref="rfc3987"/>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:resolve-uri</code></td><td rowspan="1" colspan="1">Resolves a relative IRI reference against an absolute IRI.</td></tr></tbody></table><div2 id="func-decode-from-uri"><head>fn:decode-from-uri</head><changes><change issue="600" PR="631" date="2023-09-12">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Decodes URI-escaped characters in a string.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="decode-from-uri" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>This function returns the original representation of a URI-escaped string.</p><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the zero-length
            string.</p><p>Otherwise, the value is first converted to a sequence of octets. Each plus sign
            (<code nobreak="false">+</code>) is replaced with the octet representing a space character
            (<code nobreak="false">x20</code>), and any substring that matches the regular expression
            <code nobreak="false">%[a-fA-F0-9][a-fA-F0-9]</code> is replaced with an octet for the two-digit
            hexadecimal number that follows the percent sign. Characters that are not part of
            such a substring are replaced with the octets of their UTF-8 encoding.
            For example, <code nobreak="false">"A%42+C"</code> results in the octets <code nobreak="false">x41</code>,
            <code nobreak="false">x42</code>, <code nobreak="false">x20</code>, <code nobreak="false">x43</code>, and <code nobreak="false">"💡"</code> yields
            <code nobreak="false">xF0</code>, <code nobreak="false">x9F</code>, <code nobreak="false">x92</code>, and <code nobreak="false">xA1</code>.</p><p>If <code nobreak="false">%</code> is followed by up to two characters that are not hexadecimal digits,
            these characters are replaced by octets <code nobreak="false">xEF</code>, <code nobreak="false">xBF</code>,
            and <code nobreak="false">xBD</code>, that is, the UTF-8 encoding of the Unicode replacement character
            (<char>U+FFFD</char>). For example, the incomplete or invalid percent-encoded strings
            <code nobreak="false">"%"</code>, <code nobreak="false">"%X"</code>, <code nobreak="false">"%AX"</code>, and <code nobreak="false">"%XA"</code> are all
            replaced with these octets. For the string <code nobreak="false">"%1X!"</code>, the octets <code nobreak="false">xEF</code>,
            <code nobreak="false">xBF</code>, <code nobreak="false">xBD</code>, and <code nobreak="false">x21</code> are returned.</p><p>Next, the resulting octets are interpreted as UTF-8. For example,
            <code nobreak="false">x41</code>, <code nobreak="false">x42</code>, <code nobreak="false">x20</code>, and <code nobreak="false">x43</code>
            becomes <code nobreak="false">"AB C"</code>, and <code nobreak="false">xF0</code>, <code nobreak="false">x9F</code>,
            <code nobreak="false">x92</code>, and <code nobreak="false">xA1</code> becomes <code nobreak="false">"💡"</code>.</p><p>If an invalid UTF-8 octet sequence is encountered, the octets that have
            successfully been parsed are replaced with a Unicode replacement character.
            Examples:</p><ulist><item><p>The single octet <code nobreak="false">xF0</code> is converted to <code nobreak="false">"�"</code>.</p></item><item><p>The octets <code nobreak="false">xF0</code>, <code nobreak="false">x9F</code>, <code nobreak="false">x92</code>, and
               <code nobreak="false">x41</code> are converted to <code nobreak="false">"�A"</code>:
               The bit pattern of the first octet indicates that the UTF-8 character comprises
               four octets. As the fourth octet is invalid, a Unicode replacement character is
               added for the first three octets, and the fourth (invalid) octet is parsed as a
               new character.</p></item><item><p>Similarly, the octets <code nobreak="false">xF0</code>, <code nobreak="false">xF0</code>, <code nobreak="false">x9F</code>,
               <code nobreak="false">x92</code>, and <code nobreak="false">xA1</code> are converted to <code nobreak="false">"�💡"</code>:
               The second octet is invalid, but it becomes valid when being parsed as the
               first octet of the remaining UTF-8 sequence.</p></item></ulist><p>Similarly, a UTF-8 octet sequence that represents a codepoint that is not a
            valid XML character is replaced with a Unicode replacement character.
            For example, <code nobreak="false">x00</code> becomes <code nobreak="false">"�"</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">decode-from-uri("http://example.com/")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://example.com/"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">decode-from-uri("~b%C3%A9b%C3%A9?a=b+c")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"~bébé?a=b c"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">decode-from-uri("%00-%XX-%F0%9F%92%41-%F0%F0%9F%92%A1")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"�-�-�A-�💡"</code></p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-encode-for-uri"><head>fn:encode-for-uri</head><glist><gitem><label>Summary</label><def><p>Encodes reserved characters in a string that is intended to be used in the path segment
            of a URI.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="encode-for-uri" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the zero-length
            string.</p><p>This function applies the URI escaping rules defined in section 2 of <bibref ref="rfc3986"/> to the <code nobreak="false">xs:string</code> supplied as <code nobreak="false">$value</code>. The
            effect of the function is to escape reserved characters. Each such character in the
            string is replaced with its percent-encoded form as described in <bibref ref="rfc3986"/>.</p><p>Since <bibref ref="rfc3986"/> recommends that, for consistency, URI producers and
            normalizers should use uppercase hexadecimal digits for all percent-encodings, this
            function must always generate hexadecimal values using the upper-case letters A-F.</p></def></gitem><gitem><label>Notes</label><def><note><p>All characters are escaped except those identified as “unreserved” by <bibref ref="rfc3986"/>, that is the upper- and lower-case letters <code nobreak="false">A</code> to <code nobreak="false">Z</code>,
            the digits <code nobreak="false">0</code> to <code nobreak="false">9</code>, HYPHEN-MINUS (<code nobreak="false">-</code>),
            LOW LINE (<code nobreak="false">_</code>), FULL STOP (<code nobreak="false">.</code>), and TILDE (<code nobreak="false">~</code>).</p><p>This function escapes URI delimiters and therefore cannot be used indiscriminately to
            encode “invalid” characters in a path segment.</p><p>This function is invertible but not idempotent. This is because a string containing a
            percent character will be modified by applying the function: for example
               <code nobreak="false">100%</code> becomes <code nobreak="false">100%25</code>, while <code nobreak="false">100%25</code> becomes
               <code nobreak="false">100%2525</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">encode-for-uri(
  "http://example.com/00/Weather/CA/Los%20Angeles#ocean"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"http%3A%2F%2Fexample.com%2F00%2FWeather%2FCA%2FLos%2520Angeles%23ocean"</eg><p><emph>(This is probably not what the user intended because all of the
                  delimiters have been encoded.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">concat(
  "http://example.com/",
  encode-for-uri("~bébé")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"http://example.com/~b%C3%A9b%C3%A9"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">concat(
  "http://example.com/",
  encode-for-uri("100% organic")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"http://example.com/100%25%20organic"</eg></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-escape-html-uri"><head>fn:escape-html-uri</head><glist><gitem><label>Summary</label><def><p>Escapes a URI in the same way that HTML user agents handle attribute values expected to
            contain URIs.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="escape-html-uri" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the zero-length
            string.</p><p>Otherwise, the function escapes all <termref def="character">characters</termref> except
            printable characters of the US-ASCII coded character set, specifically the <termref def="codepoint">codepoints</termref> between 32 and 126 (decimal) inclusive. Each
            character in <code nobreak="false">$value</code> to be escaped is replaced by an escape sequence, which is
            formed by encoding the character as a sequence of octets in UTF-8, and then representing
            each of these octets in the form %HH, where HH is the hexadecimal representation of the
            octet. This function must always generate hexadecimal values using the upper-case
            letters A-F.</p></def></gitem><gitem><label>Notes</label><def><note><p>The behavior of this function corresponds to the recommended handling of non-ASCII
            characters in URI attribute values as described in <bibref ref="HTML40"/> Appendix
            B.2.1.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">escape-html-uri(
  "http://www.example.com/00/Weather/CA/Los Angeles#ocean"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"http://www.example.com/00/Weather/CA/Los Angeles#ocean"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">escape-html-uri(
  "javascript:if (navigator.browserLanguage == 'fr') window.open('http://www.example.com/~bébé');"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"javascript:if (navigator.browserLanguage == 'fr') window.open('http://www.example.com/~b%C3%A9b%C3%A9');"</eg></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-iri-to-uri"><head>fn:iri-to-uri</head><glist><gitem><label>Summary</label><def><p>Converts a string containing an IRI into a URI according to the rules of <bibref ref="rfc3987"/>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="iri-to-uri" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the zero-length
            string.</p><p>Otherwise, the function converts <code nobreak="false">$value</code> into a URI according to
            the rules given in Section 3.1 of <bibref ref="rfc3987"/> by percent-encoding characters
            that are allowed in an IRI but not in a URI. If <code nobreak="false">$value</code> contains a character
            that is invalid in an IRI, such as the space character (see note below), the invalid
            character is replaced by its percent-encoded form as described in <bibref ref="rfc3986"/> before the conversion is performed.</p><p>Since <bibref ref="rfc3986"/> recommends that, for consistency, URI producers and
            normalizers should use uppercase hexadecimal digits for all percent-encodings, this
            function must always generate hexadecimal values using the upper-case letters A-F.</p></def></gitem><gitem><label>Notes</label><def><note><p>The function is idempotent but not invertible. Both the inputs <code nobreak="false">My Documents</code>
            and <code nobreak="false">My%20Documents</code> will be converted to the output
               <code nobreak="false">My%20Documents</code>.</p><p>This function does not check whether <code nobreak="false">$iri</code> is a valid IRI. It treats it as
            an <termref def="string">string</termref> and operates on the <termref def="character">characters</termref> in the string.</p><p> The following printable ASCII characters are invalid in an IRI: <code nobreak="false">&lt;</code>, <code nobreak="false">&gt;</code>,
            <code nobreak="false">"</code>, <code nobreak="false"> </code>, <code nobreak="false">{</code>, <code nobreak="false">}</code>, <code nobreak="false">|</code>,
            <code nobreak="false">\</code>, <code nobreak="false">^</code>, and <code nobreak="false">`</code>. Since these
            characters should not appear in an IRI, if they do appear in <code nobreak="false">$iri</code> they will
            be percent-encoded. In addition, characters outside the range <char>U+0020</char> to <char>U+007E</char> will be
            percent-encoded because they are invalid in a URI. </p><p> Since this function does not escape the character <char>U+0025</char> and this character is not
            allowed in data within a URI, users wishing to convert character strings (such as file
            names) that include <code nobreak="false">%</code> to a URI should manually escape <code nobreak="false">%</code>
            by replacing it with <code nobreak="false">%25</code>.
         </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">iri-to-uri(
  "http://www.example.com/00/Weather/CA/Los%20Angeles#ocean"
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"http://www.example.com/00/Weather/CA/Los%20Angeles#ocean"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">iri-to-uri("http://www.example.com/~bébé")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://www.example.com/~b%C3%A9b%C3%A9"</code></p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-resolve-uri"><head>fn:resolve-uri</head><changes><change issue="895" PR="901" date="2023-12-16">The optional second argument can now be supplied as the empty sequence.</change></changes><glist><gitem><label>Summary</label><def><p>Resolves a relative IRI reference against an absolute IRI.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="resolve-uri" return-type="xs:anyURI?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="href" type="xs:string?"/><arg name="base" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The function is defined to operate on IRI references as defined in <bibref ref="rfc3987"/>, and the implementation <rfc2119>must</rfc2119> permit all arguments that are valid
            according to that specification. In addition, the implementation <rfc2119>may</rfc2119>
            accept some or all strings that conform to the rules for (absolute or relative) Legacy
            Extended IRI references as defined in <bibref ref="LEIRI"/>. For the purposes of this
            section, the terms IRI and IRI reference include these extensions, insofar as the
            implementation chooses to support them.</p><p>The following rules apply in order:</p><olist><item><p>If <code nobreak="false">$href</code> is the empty sequence, the function returns the empty
               sequence.</p></item><item><p>If <code nobreak="false">$href</code> is an absolute IRI (as defined above), then it is returned
               unchanged.</p></item><item><p>If the <code nobreak="false">$base</code> argument is the empty sequence, then:</p><olist><item><p>If the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> 
                        in the dynamic context is not absent, it is used as the effective
                        value of <code nobreak="false">$base</code>.</p></item><item><p>Otherwise, a dynamic error is raised: <phrase><errorref class="NS" code="0005"/></phrase>.</p></item></olist></item><item><p>The function resolves the relative IRI reference <code nobreak="false">$href</code>
               against the base IRI <code nobreak="false">$base</code> using the algorithm defined in <bibref ref="rfc3986"/>, adapted by treating any <termref def="character">character</termref>
               that would not be valid in an RFC3986 URI or relative reference in the same way that
               RFC3986 treats unreserved characters. No percent-encoding takes place.</p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>The first form of this function resolves <code nobreak="false">$href</code> against the value of the
            base-uri property from the static context. A dynamic error is raised <errorref class="NS" code="0005"/> if the base-uri property is not initialized in the static
            context. </p><p>A dynamic error is raised <errorref class="RG" code="0002"/> if <code nobreak="false">$href</code>
            is not a valid IRI according to the rules of RFC3987, extended with an
            implementation-defined subset of the extensions permitted in LEIRI, or if it is not a
            suitable relative reference to use as input to the RFC3986 resolution algorithm extended
            to handle additional unreserved characters. </p><p>A dynamic error is raised <errorref class="RG" code="0002"/> if <code nobreak="false">$base</code> is
            not a valid IRI according to the rules of RFC3987, extended with an
            implementation-defined subset of the extensions permitted in LEIRI, or if it is not a
            suitable IRI to use as input to the chosen resolution algorithm (for example, if it is a
            relative IRI reference<phrase diff="add" at="2023-04-04"> or</phrase><phrase diff="del" at="2023-04-04">,</phrase> if it is a non-hierarchic URI<phrase diff="del" at="2023-04—04">, or if it contains a fragment
            identifier</phrase>).<phrase diff="add" at="2023-04-04"> In XPath 4.0, attempting
         to resolve against an absolute URI that includes a fragment identifier is no longer
         an error, the fragment identifier is simply ignored. A narrow reading of RFC 3986
         might seem to forbid this, but in practice the interpretation is non-controversial
         and the practice is widely supported.</phrase></p><p>A dynamic error is raised <errorref class="RG" code="0009"/> if the chosen resolution
            algorithm fails for any other reason. </p></def></gitem><gitem><label>Notes</label><def><note><p>Resolving a URI does not dereference it. This is merely a syntactic operation on two
               <termref def="string">strings</termref>.</p><p>The algorithms in the cited RFCs include some variations that are optional or
            recommended rather than mandatory; they also describe some common practices that are not
            recommended, but which are permitted for backwards compatibility. Where the cited RFCs
            permit variations in behavior, so does this specification. </p><p>Throughout this family of specifications, the phrase "resolving a relative URI (or IRI)
            reference" should be understood as using the rules of this function, unless otherwise
            stated.</p><p>RFC3986 defines an algorithm for resolving relative references 
            in the context of the URI syntax defined in that RFC. RFC3987 describes a modification 
            to that algorithm to make it applicable to IRIs (specifically: additional characters 
            permitted in an IRI are handled the same way that RFC3986 handles unreserved characters). 
            The LEIRI specification does not explicitly define a resolution algorithm, but suggests 
            that it <emph>should not</emph> be done by converting the LEIRI to a URI, and 
            <emph>should not</emph> involve percent-encoding. This specification fills this gap 
            by defining resolution for LEIRIs in the same way that RFC3987 defines resolution for IRIs,
            that is by specifying that additional characters are handled as unreserved characters.</p></note></def></gitem></glist></div2><div2 id="parse-build"><head>Parsing and building URIs</head><p>This section specifies functions that parse strings as
         URIs, to identify their structure, and construct URI strings
         from their structured representation.</p><p>Some URI schemes are hierarchical and some are non-hierarchical.
         Implementations must treat the following schemes as non-hierarchical:
         <code nobreak="false">jar</code>, <code nobreak="false">mailto</code>, <code nobreak="false">news</code>, <code nobreak="false">tag</code>,
         <code nobreak="false">tel</code>, and <code nobreak="false">urn</code>. Whether additional schemes
         are known to be non-hierarchical
         <termref def="implementation-defined">implementation-defined</termref>.
         If a scheme is not known to be non-hierarchical, it must be
         treated as hierarchical.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-uri</code></td><td rowspan="1" colspan="1">Parses the URI provided and returns a map of its parts.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:build-uri</code></td><td rowspan="1" colspan="1">Constructs a URI from the parts provided.</td></tr></tbody></table><p>Both functions use a structured representation of a URI as defined in the next section.</p><div3 id="uri-structure-record"><head>Record fn:uri-structure-record</head><p>This record type represents the components of a URI.</p><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Name</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">uri?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The original URI. This element is returned by <function>fn:parse-uri</function>,
            but ignored by <function>fn:build-uri</function>.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">scheme?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The URI scheme (e.g., “https” or “file”).</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">absolute?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The URI is an absolute URI.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">hierarchical?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>Whether the URI is hierarchical or not.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">authority?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The authority portion of the URI (e.g., “example.com:8080”).</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">userinfo?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>Any userinfo that was passed as part of the authority.</p><ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">host?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>The host passed as part of the authority (e.g., “example.com”). </p><ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">port?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>The port passed as part of the authority (e.g., “8080”).</p><ulist><item><p><term>Type: </term><code nobreak="false">xs:integer?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">path?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>The path portion of the URI.</p><ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">query?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>Any query string.</p><ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">fragment?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>Any fragment identifier.</p><ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">path-segments?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>Parsed and unescaped path segments.</p><ulist><item><p><term>Type: </term><code nobreak="false">xs:string*</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">query-parameters?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>Parsed and unescaped query key-value pairs.</p><ulist><item><p><term>Type: </term><code nobreak="false">map(xs:string, xs:string*)?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">filepath?</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>The path of the URI, treated as a filepath.</p><ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr></tbody></table><p>The segmented forms of the path and query parameters provide
           convenient access to commonly used information.</p><p>The path, if there is one, is tokenized on “/” characters and
           each segment is unescaped (as per the <function>fn:decode-from-uri</function> function). Consider the URI
           <code nobreak="false">http://example.com/path/to/a%2fb</code>.
           The path portion has to be returned as <code nobreak="false">/path/to/a%2fb</code> because
           decoding the <code nobreak="false">%2f</code> would change the nature of the path.
           The unescaped form is easily accessible from <code nobreak="false">path-segments</code>:</p><eg xml:space="preserve">("", "path", "to", "a/b")</eg><p>Note that the presence or absence of a leading slash on the path
           will affect whether or not the sequence begins with a zero-length string.</p><p>The query parameters are decoded into a map. Consider the URI:
           <code nobreak="false">http://example.com/path?a=1&amp;b=2%264&amp;a=3</code>.
           The decoded form in the query-parameters is the following map:</p><eg xml:space="preserve">{ "a": ("1", "3"), "b": "2&amp;4" }</eg><p>Note that both keys and values are unescaped. If a key
           is repeated in the query string, the map will contain a
           sequence of values for that key, as seen for <code nobreak="false">a</code>
           in this example.</p></div3><div3 id="func-parse-uri"><head>fn:parse-uri</head><changes><change date="2022-10-17" PR="215 415 " issue="72 389 390">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Parses the URI provided and returns a map of its parts.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-uri" return-type-ref="uri-structure-record" return-type-ref-occurs="?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the result is the empty sequence.</p><p>The function parses the <code nobreak="false">$value</code> provided,
         returning a map containing its constituent parts: scheme,
         authority components, path, etc.
         In addition to parsing URIs as defined by <bibref ref="rfc3986"/>
         (and <bibref ref="rfc3987"/>), this function also attempts to
         account for strings that are not valid URIs but that often appear
         in URI-adjacent spaces, such as file names. Not all such strings
         can be successfully parsed as URIs.</p><p>The following options are available:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="allow-deprecated-features" type="xs:boolean" occur="opt"/><arg name="omit-default-ports" type="xs:boolean" occur="opt"/><arg name="unc-path" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">allow-deprecated-features?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Indicates that deprecated URI
               features should be returned<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">omit-default-ports?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Indicates that a port number that is the same as
               the default port for a given scheme should be omitted.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">unc-path?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Indicates that an input URI that begins
               with two or more leading slashes should be interprted
               as a Windows Universal Naming Convention
               Path. (Specifically: that it has the <code nobreak="false">file:</code> scheme.)<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr></tbody></table><p>This function is described as a series of transformations
         over the input string to identify the parts of a URI that are
         present. Some portions of the URI are identified by matching
         with a regular expression. This approach is designed to make
         the description clear and unambiguous; it is not implementation
         advice. Comparison of <emph>scheme</emph> and <emph>authority</emph>
         components is case insensitive.</p><p>Processing begins with a <emph>string</emph> that is equal
         to the <code nobreak="false">$value</code>. If the <emph>string</emph> contains
         any backslashes (<code nobreak="false">\</code>), replace them with forward
         slashes (<code nobreak="false">/</code>).</p><p>Strip off the fragment identifier and any query:</p><ulist><item><p>If the <emph>string</emph> matches <code nobreak="false">^(.*?)#(.*)$</code>, the
         <emph>string</emph> is the first match group and the
         <emph>fragment</emph> is the second match group. Otherwise, the string
         is unchanged and the <emph>fragment</emph> is the empty sequence. If a
         fragment is present, it is URI decoded. If the fragment is a zero-length
         string, it is discarded and the <emph>fragment</emph> is the empty
         sequence.</p></item><item><p>If the <emph>string</emph> matches <code nobreak="false">^(.*?)\?(.*)$</code>,
         the <emph>string</emph> is the first match group and the
         <emph>query</emph> is the second match group. Otherwise,
         the string is unchanged and the <emph>query</emph> is the empty
         sequence. If the query is a zero-length
         string, it is discarded and the <emph>query</emph> is the empty
         sequence.</p></item></ulist><p>Attempt to identify the scheme:</p><ulist><item><p>If the <emph>string</emph> matches
               <code nobreak="false">^([a-zA-Z][A-Za-z0-9\+\-\.]+):(.*)$</code>:</p><ulist><item><p>the <emph>scheme</emph> is the first match group and</p></item><item><p>the <emph>string</emph> is the second match group.</p></item></ulist></item><item><p>Otherwise, the <emph>scheme</emph> is the empty sequence and the
               <emph>string</emph> is unchanged.</p></item></ulist><p>If the <emph>scheme</emph> is not empty and the <emph>fragment</emph> is empty,
         <emph>absolute</emph> is true. Otherwise, <emph>absolute</emph> is the empty
         sequence. (But see the discussion of hierarchical URIs, below.)</p><p>If <emph>scheme</emph> is the empty sequence or <code nobreak="false">file</code>:</p><ulist><item><p>If the <emph>string</emph> matches <code nobreak="false">^/*([a-zA-Z][:|].*)$</code>:</p><ulist><item><p>the <emph>scheme</emph> is <code nobreak="false">file</code> and</p></item><item><p>the <emph>string</emph> is a single slash <code nobreak="false">/</code> followed
                  by the first match group with the
                  second character changed to <code nobreak="false">:</code>, if necessary.</p></item></ulist></item><item><p>Otherwise, if <emph>unc-path</emph> is <code nobreak="false">true</code>:</p><ulist><item><p>the <emph>scheme</emph> is <code nobreak="false">file</code> and</p></item><item><p>the <emph>string</emph> is unchanged.</p></item></ulist></item><item><p>Finally, if neither of the preceding cases apply:</p><ulist><item><p>the <emph>scheme</emph> remains the empty sequence and</p></item><item><p>the <emph>string</emph> is unchanged.</p></item></ulist></item></ulist><p>Now that the scheme, if there is one, has been identified,
         determine if the URI is hierarchical:</p><ulist><item><p>If the <emph>scheme</emph> is known to be hierarchical, or known
         not to be hierarchical, then <emph>hierarchical</emph> is set accordingly.
         If the implementation does not know if a <emph>scheme</emph> is or is not
         hierarchical, the <emph>hierarchical</emph> setting depends on the
         <emph>string</emph>: if the <emph>string</emph> is the zero-length string,
         <emph>hierarchical</emph> is the empty sequence (<emph>i.e.</emph> not known),
         otherwise <emph>hierarchical</emph> is
         <code nobreak="false">true</code> if <emph>string</emph> begins with <code nobreak="false">/</code> and
         <code nobreak="false">false</code> otherwise.</p></item></ulist><p>If the URI is not <emph>hierarchical</emph>, <emph>absolute</emph>
         is the empty sequence.</p><p>Identify the remaining components according to the scheme and whether
         or not the URI is hierarchical.</p><ulist><item><p>If the scheme is <code nobreak="false">file</code>:</p><ulist><item><p>The <emph>authority</emph> is the empty sequence.</p></item><item><p>If <emph>unc-path</emph> is true and the string
                     matches <code nobreak="false">^/*(//[^/].*)$</code>: then <emph>filepath</emph>,
                     and <emph>string</emph> are both the first match group.</p></item><item><p>If the <emph>string</emph> begins <code nobreak="false">^//*[A-Za-z]:/</code> then
                     all but one leading slash is removed from <emph>string</emph> and the
                     <emph>filepath</emph> is the <emph>string</emph> with all leading slashes removed.</p></item><item><p>Otherwise, the <emph>filepath</emph>
                     and <emph>string</emph> are the <emph>string</emph>
                     with any sequence of leading slashes replaced by a single slash.</p></item></ulist></item><item><p>If the scheme is <code nobreak="false">hierarchical</code>:</p><ulist><item><p>If the <emph>string</emph>
                     matches <code nobreak="true">^//([^/]+)$</code>, the <emph>authority</emph>
                     is the first match group and the <emph>string</emph> is empty.</p></item><item><p>If the <emph>string</emph>
                     matches <code nobreak="true">^//([^/]*)(/.*)$</code>, the <emph>authority</emph>
                     is the first match group and the <emph>string</emph> is the second
                     match group.</p></item><item><p>Otherwise,
                     the <emph>authority</emph> is the empty sequence
                     and the <emph>string</emph> is unchanged.</p></item></ulist></item><item><p>If the scheme is not <code nobreak="false">hierarchical</code>:</p><ulist><item><p>The <emph>authority</emph> is the empty sequence
                     and the <emph>string</emph> is unchanged.</p></item></ulist></item></ulist><p>If the <emph>authority</emph> matches
         <code nobreak="false">^(([^@]*)@)(.*)(:([^:]*))?$</code>,
         then the <emph>userinfo</emph> is match group 2, otherwise
         <emph>userinfo</emph> is the empty sequence. If
         <emph>userinfo</emph> is present and contains a non-empty password, then
         <emph>userinfo</emph> is discarded and set to the empty sequence
         unless the <code nobreak="false">allow-deprecated-features</code> option is <code nobreak="false">true</code>.</p><p>When parsing the <emph>authority</emph> to find the <emph>host</emph>,
         there are four possibilities: the host can be a registered name (e.g.,
         <code nobreak="false">example.com</code>), an IPv4 address (e.g., <code nobreak="false">127.0.0.1</code>),
         an IPv6 (or IPvFuture) address (e.g., <code nobreak="false">[::1]</code>), or an error
         if there is an open square bracket (<code nobreak="false">[</code>) not matched by a
         close square bracket (<code nobreak="false">]</code>). In a properly
         constructed RFC 3986 URI, the only place where square
         brackets may occur is around the IPv6/IPvFuture IP address.</p><olist><item><p>If the <emph>authority</emph> matches
               <code nobreak="false">^(([^@]*)@)?(\[[^\]]*\])(:([^:]*))?$</code>,
               then the <emph>host</emph> is match group 3, otherwise
               </p></item><item><p>If the <emph>authority</emph> matches
               <code nobreak="false">^(([^@]*)@)?\[.*$</code>
               then <errorref class="UR" code="0001"/> is raised, otherwise
               </p></item><item><p>If the <emph>authority</emph> matches
               <code nobreak="false">^(([^@]*)@)?([^:]+)(:([^:]*))?$</code>,
               then the <emph>host</emph> is match group 3, otherwise
               </p></item><item><p>the <emph>host</emph> is the empty sequence.</p></item></olist><p>This function does not attempt to decode the components of the
         <emph>host</emph>.</p><p>Similar care must be taken to match the port because an IPv6/IPvFuture
         address may contain a colon.</p><ulist><item><p>If the <emph>authority</emph> matches
               <code nobreak="false">^(([^@]*)@)?(\[[^\]]*\])(:([^:]*))?$</code>,
               then the <emph>port</emph> is match group 5.
               </p></item><item><p>Otherwise, if the <emph>authority</emph> matches
               <code nobreak="false">^(([^@]*)@)?([^:]+)(:([^:]*))?$</code>,
               then the <emph>port</emph> is match group 5.
               </p></item><item><p>Otherwise, the <emph>port</emph> is the empty sequence.</p></item></ulist><p>If the <code nobreak="false">omit-default-ports</code> option is <code nobreak="false">true</code>,  the port
         is discarded and set to the empty sequence if the port number is the same
         as the default port for the given scheme. Implementations <rfc2119>should</rfc2119>
         recognize the default ports for <code nobreak="false">http</code> (80), <code nobreak="false">https</code> (443),
         <code nobreak="false">ftp</code> (21), and <code nobreak="false">ssh</code> (22). Exactly which ports are
         recognized
         is <termref def="implementation-defined">implementation-defined</termref>.
         </p><p>If the <emph>string</emph> is a zero-length string, then
         <emph>path</emph> is the empty sequence, otherwise <emph>path</emph>
         is the whole <emph>string</emph>. If the <emph>scheme</emph> is 
         the empty sequence, <emph>filepath</emph> is also the whole <emph>string</emph>.</p><p>A <emph>path-segments</emph> sequence is constructed by tokenizing
         the <emph>string</emph> on <code nobreak="false">/</code> (solidus) and applying
         <emph>uri decoding</emph> on each token.</p><note><p>The <emph>path</emph> and <emph>path-segments</emph> properties both contain
         the path portion of the URI. The different formats
         only become important when the path contains encoded delimiters.</p><p>Consider <code nobreak="false">/path%2Fsegment</code>. An application may want to decode that,
         using <code nobreak="false">/path/segment</code> in a database query, for example. At the same
         time, an application may wish to modify the URI and then reconstruct it.</p><p>In the string form, decoding <code nobreak="false">%2F</code> to <code nobreak="false">/</code> is
         not reversible. In the <emph>path-segments</emph> form, the path is
         broken into discrete segments where the syntactic delimiters occur.
         This means the encoded delimiters can be decoded without introducing
         ambiguity: <code nobreak="false">("", "path/segment")</code>. In this format, the
         decoding is reversible: escape the non-syntactic delimiters before
         reconstructing the path with the syntactic ones.</p><p>A consequence of constructing the <emph>path-segments</emph> this
         way is that a zero-length string appears before the first <code nobreak="false">/</code>,
         if the path begins with a
         <code nobreak="false">/</code>, after the last
         <code nobreak="false">/</code>, if the path ends with a
         <code nobreak="false">/</code>, and between consecutive
         <code nobreak="false">/</code> characters. (If the path consists of a single <code nobreak="false">/</code>,
         that <code nobreak="false">/</code> counts as <emph>both</emph> the first and last <code nobreak="false">/</code>,
         producing a segment list containing two empty strings.)</p><p>The
         empty strings may seem unnecessary at first glance, but they assure
         that the path can be reconstructed by joining the segments together
         again without having to handle the presence or absence of a leading or
         trailing <code nobreak="false">/</code> as special cases.</p></note><p>Applying <emph>uri decoding</emph> is equivalent to
         calling <function>fn:decode-from-uri</function> on the string.</p><p>The <emph>query-parameters</emph> value is constructed as follows.
         Start with the empty map. Tokenize the <emph>query</emph> on
         the <code nobreak="false">&amp;</code> (ampersand). For each token, identify
         the <emph>key</emph> and the <emph>value</emph>. If the token
         contains an equal sign (<code nobreak="false">=</code>), the <emph>key</emph>
         is the string that precedes the first equal sign, uri
         decoded, and the <emph>value</emph> is the remainder
         of the token, after the first equal sign, uri decoded. If the
         token does not contain an equal sign, <emph>key</emph> is the
         empty string and the <emph>value</emph> is equal to the
         token, uri decoded. Add the <emph>key</emph>/<emph>value</emph> pair
         to the map. If the <emph>key</emph> already exists in the map, add the <emph>value</emph>
         to a list of values associated with that key. The resulting map, when all
         tokens have been processed, is the <emph>query-parameters</emph> map.</p><p>If the <emph>filepath</emph> is not the empty sequence,
         it is uri decoded. On a Windows system, any
         forward slashes in the path <rfc2119>may</rfc2119> be
         replaced with backslashes.</p><p>A <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#uri-structure-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">uri-structure-record</loc> is returned.
         The record should be populated with only those keys that have a non-empty value (keys
         whose value is the empty sequence <rfc2119>should</rfc2119>
         be omitted).</p><p>Implementations may implement additional or different rules for URIs that
         have a scheme or pattern that they recognize. An implementation might choose
         to parse <code nobreak="false">jar:</code> URIs with special rules, for example, since they extend the
         syntax in ways not defined by <bibref ref="rfc3986"/>. Implementations may add
         additional keys to the map. The meaning of those keys is implementation-defined.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="UR" code="0001"/> if
         the URI contains an open square bracket in the authority component that
         is not followed by a close square bracket.</p></def></gitem><gitem><label>Notes</label><def><note><p>Like <function>fn:resolve-uri</function>, this function handles the additional characters
         allowed in <bibref ref="rfc3987"/> IRIs in the same way that other unreserved
         characters are handled.</p><p>Unlike <function>fn:resolve-uri</function>, this function is not attempting to resolve
         one URI against another and consequently, the errors that can arise under those
         circumstances do not apply here. The <function>fn:parse-uri</function> function will
         accept strings that would raise errors if resolution was attempted;
         see <function>fn:build-uri</function>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>In the examples that follow, keys with values that are null or the empty sequence
    are elided for editorial clarity. String literals that include an ampersand character
    are written as string templates (for example <code nobreak="false">`Barnes&amp;Noble`</code>) to ensure
    that the examples work in both XPath and XQuery.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("http://qt4cg.org/specifications/xpath-functions-40/Overview.html#parse-uri")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "qt4cg.org",
  "fragment": "parse-uri",
  "hierarchical": true(),
  "host": "qt4cg.org",
  "path": "/specifications/xpath-functions-40/Overview.html",
  "path-segments": ("", "specifications", "xpath-functions-40", "Overview.html"),
  "scheme": "http",
  "uri": "http://qt4cg.org/specifications/xpath-functions-40/Overview.html#parse-uri"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("http://www.ietf.org/rfc/rfc2396.txt")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "www.ietf.org",
  "hierarchical": true(),
  "absolute": true(),
  "host": "www.ietf.org",
  "path": "/rfc/rfc2396.txt",
  "path-segments": ("", "rfc", "rfc2396.txt"),
  "scheme": "http",
  "uri": "http://www.ietf.org/rfc/rfc2396.txt"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("https://example.com/path/to/file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "example.com",
  "path": "/path/to/file",
  "scheme": "https",
  "path-segments": ("", "path", "to", "file"),
  "host": "example.com",
  "hierarchical": true(),
  "absolute": true(),
  "uri": "https://example.com/path/to/file"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri(
  `https://example.com:8080/path?s=%22hello world%22&amp;sort=relevance`
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "example.com:8080",
  "hierarchical": true(),
  "absolute": true(),
  "host": "example.com",
  "path": "/path",
  "path-segments": ("", "path"),
  "port": 8080,
  "query": `s=%22hello world%22&amp;sort=relevance`,
  "query-parameters": {
    "s": """hello world""",
    "sort": "relevance"
  },
  "scheme": "https",
  "uri": `https://example.com:8080/path?s=%22hello world%22&amp;sort=relevance`
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("https://user@example.com/path/to/file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "user@example.com",
  "hierarchical": true(),
  "absolute": true(),
  "host": "example.com",
  "path": "/path/to/file",
  "path-segments": ("", "path", "to", "file"),
  "scheme": "https",
  "uri": "https://user@example.com/path/to/file",
  "userinfo": "user"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("ftp://ftp.is.co.za/rfc/rfc1808.txt")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "ftp.is.co.za",
  "hierarchical": true(),
  "absolute": true(),
  "host": "ftp.is.co.za",
  "path": "/rfc/rfc1808.txt",
  "path-segments": ("", "rfc", "rfc1808.txt"),
  "scheme": "ftp",
  "uri": "ftp://ftp.is.co.za/rfc/rfc1808.txt"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("file:////uncname/path/to/file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "/uncname/path/to/file",
  "hierarchical": true(),
  "absolute": true(),
  "path": "/uncname/path/to/file",
  "path-segments": ("", "uncname", "path", "to", "file"),
  "scheme": "file",
  "uri": "file:////uncname/path/to/file"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("file:///c:/path/to/file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "c:/path/to/file",
  "hierarchical": true(),
  "absolute": true(),
  "path": "/c:/path/to/file",
  "path-segments": ("", "c:", "path", "to", "file"),
  "scheme": "file",
  "uri": "file:///c:/path/to/file"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("file:/C:/Program%20Files/test.jar")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "C:/Program Files/test.jar",
  "hierarchical": true(),
  "absolute": true(),
  "path": "/C:/Program%20Files/test.jar",
  "path-segments": ("", "C:", "Program Files", "test.jar"),
  "scheme": "file",
  "uri": "file:/C:/Program%20Files/test.jar"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("file:\\c:\path\to\file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "c:/path/to/file",
  "hierarchical": true(),
  "absolute": true(),
  "path": "/c:/path/to/file",
  "path-segments": ("", "c:", "path", "to", "file"),
  "scheme": "file",
  "uri": "file:\\c:\path\to\file"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("file:\c:\path\to\file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "c:/path/to/file",
  "hierarchical": true(),
  "absolute": true(),
  "path": "/c:/path/to/file",
  "path-segments": ("", "c:", "path", "to", "file"),
  "scheme": "file",
  "uri": "file:\c:\path\to\file"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("c:\path\to\file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "c:/path/to/file",
  "hierarchical": true(),
  "path": "/c:/path/to/file",
  "path-segments": ("", "c:", "path", "to", "file"),
  "scheme": "file",
  "uri": "c:\path\to\file"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("/path/to/file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "/path/to/file",
  "hierarchical": true(),
  "path": "/path/to/file",
  "path-segments": ("", "path", "to", "file"),
  "uri": "/path/to/file"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("#testing")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "fragment": "testing",
  "uri": "#testing"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("?q=1")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "query": "q=1",
  "query-parameters":{
    "q": "1"
  },
  "uri": "?q=1"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("ldap://[2001:db8::7]/c=GB?objectClass?one")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "[2001:db8::7]",
  "hierarchical": true(),
  "absolute": true(),
  "host": "[2001:db8::7]",
  "path": "/c=GB",
  "path-segments": ("", "c=GB"),
  "query": "objectClass?one",
  "query-parameters":{
    "": "objectClass?one"
  },
  "scheme": "ldap",
  "uri": "ldap://[2001:db8::7]/c=GB?objectClass?one"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("mailto:John.Doe@example.com")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "hierarchical": false(),
  "path": "John.Doe@example.com",
  "path-segments": "John.Doe@example.com",
  "scheme": "mailto",
  "uri": "mailto:John.Doe@example.com"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("news:comp.infosystems.www.servers.unix")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "hierarchical": false(),
  "path": "comp.infosystems.www.servers.unix",
  "path-segments": "comp.infosystems.www.servers.unix",
  "scheme": "news",
  "uri": "news:comp.infosystems.www.servers.unix"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("tel:+1-816-555-1212")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "hierarchical": false(),
  "path": "+1-816-555-1212",
  "path-segments": " 1-816-555-1212",
  "scheme": "tel",
  "uri": "tel:+1-816-555-1212"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("telnet://192.0.2.16:80/")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "192.0.2.16:80",
  "hierarchical": true(),
  "absolute": true(),
  "host": "192.0.2.16",
  "path": "/",
  "path-segments": ("", ""),
  "port": 80,
  "scheme": "telnet",
  "uri": "telnet://192.0.2.16:80/"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("urn:oasis:names:specification:docbook:dtd:xml:4.1.2")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "hierarchical": false(),
  "path": "oasis:names:specification:docbook:dtd:xml:4.1.2",
  "path-segments": "oasis:names:specification:docbook:dtd:xml:4.1.2",
  "scheme": "urn",
  "uri": "urn:oasis:names:specification:docbook:dtd:xml:4.1.2"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("tag:textalign.net,2015:ns")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "hierarchical": false(),
  "path": "textalign.net,2015:ns",
  "path-segments": "textalign.net,2015:ns",
  "scheme": "tag",
  "uri": "tag:textalign.net,2015:ns"
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("tag:jan@example.com,1999-01-31:my-uri")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "hierarchical": false(),
  "path": "jan@example.com,1999-01-31:my-uri",
  "path-segments": "jan@example.com,1999-01-31:my-uri",
  "scheme": "tag",
  "uri": "tag:jan@example.com,1999-01-31:my-uri"
}</eg></td></tr><tr><td colspan="2" rowspan="1"><p>This example uses the algorithm described above, not an algorithm that is
specifically aware of the <code nobreak="false">jar:</code> scheme.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("jar:file:/C:/Program%20Files/test.jar!/foo/bar")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "hierarchical": false(),
  "path": "file:/C:/Program%20Files/test.jar!/foo/bar",
  "path-segments": ("file:", "C:", "Program Files", "test.jar!", "foo", "bar"),
  "scheme": "jar",
  "uri": "jar:file:/C:/Program%20Files/test.jar!/foo/bar"
}</eg></td></tr><tr><td colspan="2" rowspan="1"><p>This example demonstrates that parsing the URI treats non-URI characters in
lexical IRIs as “unreserved characters”. The rationale for this is given in the
description of <function>fn:resolve-uri</function>.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("http://www.example.org/Dürst")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "authority": "www.example.org",
  "hierarchical": true(),
  "absolute": true(),
  "host": "www.example.org",
  "path": "/Dürst",
  "path-segments": ("", "Dürst"),
  "scheme": "http",
  "uri": "http://www.example.org/Dürst"
}</eg></td></tr><tr><td colspan="2" rowspan="1"><p>This example demonstrates the use of <code nobreak="false">|</code> instead of <code nobreak="false">:</code> in a Windows
path.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("c|/path/to/file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "c:/path/to/file",
  "hierarchical": true(),
  "path": "/c:/path/to/file",
  "path-segments": ("", "c:", "path", "to", "file"),
  "scheme": "file",
  "uri": "c|/path/to/file"
}</eg></td></tr><tr><td colspan="2" rowspan="1"><p>This example demonstrates the use of <code nobreak="false">|</code> instead of <code nobreak="false">:</code> in a Windows
path with an explicit <code nobreak="false">file:</code> scheme.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-uri("file://c|/path/to/file")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "filepath": "c:/path/to/file",
  "hierarchical": true(),
  "absolute": true(),
  "path": "/c:/path/to/file",
  "path-segments": ("", "c:", "path", "to", "file"),
  "scheme": "file",
  "uri": "file://c|/path/to/file"
}</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-build-uri"><head>fn:build-uri</head><changes><change date="2022-10-17" issue="72 389 390" PR="1423 1413">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Constructs a URI from the parts provided.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="build-uri" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="parts" type-ref="uri-structure-record"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>A URI is composed from a scheme, authority, path, query, and fragment.</p><p>The following options are available:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="allow-deprecated-features" type="xs:boolean" occur="opt"/><arg name="omit-default-ports" type="xs:boolean" occur="opt"/><arg name="unc-path" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">allow-deprecated-features?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Indicates that deprecated URI
              features should be returned<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">omit-default-ports?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Indicates that a port number that is the same as
              the default port for a given scheme should be omitted.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">unc-path?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Indicates that the URI represents
               a Windows Universal Naming Convention
               Path.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr></tbody></table><p>The components are derived from the contents of the
        <code nobreak="false">$parts</code> map. To simplify the description below, a
        value is considered to be present in the map if the relevant
        field exists and is non-empty.</p><p>If the <code nobreak="false">scheme</code> key is present in the map,
        the URI begins with the value of that key. A URI is considered to be
        non-hierarchical if either the <code nobreak="false">hierarchical</code> key
        is present in the <code nobreak="false">$parts</code> map with the value
        <code nobreak="false">false</code> or if the scheme is known to be
        non-hierarchical. (In other words, schemes are hierarchical by
        default.)</p><ulist><item><p>If the <code nobreak="false">scheme</code> is
        known to be non-hierarchical, it is delimited by a trailing
        <code nobreak="false">:</code>.</p></item><item><p>Otherwise, if the <code nobreak="false">scheme</code> is <code nobreak="false">file</code> and the <code nobreak="false">unc-path</code>
        option is <code nobreak="false">true</code>, the scheme is delimited by a trailing <code nobreak="false">:////</code>.</p></item><item><p>Otherwise, the scheme is delimited by
        a trailing <code nobreak="false">://</code>.</p></item></ulist><p>For simplicity of exposition, we take the
        <code nobreak="false">userinfo</code>, <code nobreak="false">host</code>, and
        <code nobreak="false">port</code> values from the map and imagine they are
        stored in variables with the same name. If the key is not
        present in the map, the value of the variable is set to the
        empty sequence.</p><p>If <code nobreak="false">$userinfo</code> is non-empty and contains a
        non-empty password, then <code nobreak="false">$userinfo</code> is set to the
        empty sequence unless the
        <code nobreak="false">allow-deprecated-features</code> option is <code nobreak="false">true</code>.</p><p>If the <code nobreak="false">omit-default-ports</code> option is <code nobreak="false">true</code>
        then the <code nobreak="false">$port</code> is set to the empty sequence if
        the port number is the same as the default port for the given
        scheme. Implementations <rfc2119>should</rfc2119> recognize
        the default ports for <code nobreak="false">http</code> (80),
        <code nobreak="false">https</code> (443), <code nobreak="false">ftp</code> (21), and
        <code nobreak="false">ssh</code> (22). Exactly which ports are recognized is
        <termref def="implementation-defined">implementation-defined</termref>.
        </p><p>If any of <code nobreak="false">$userinfo</code>, <code nobreak="false">$host</code>, or <code nobreak="false">$port</code>
        exist, the following authority is added to the URI under construction:
        <eg xml:space="preserve">concat(
  if (exists($userinfo)) { $userinfo || "@" },
  $host,
  if (exists($port)) { ":" || $port }
)</eg></p><p>If none of <code nobreak="false">userinfo</code>, <code nobreak="false">host</code>, or <code nobreak="false">port</code>
        is present, and <code nobreak="false">authority</code> is present, the value of the
        <code nobreak="false">authority</code> key is added to the URI. (In this case, no attempt
        is made to determine if a password or standard port are present,
        the <code nobreak="false">authority</code> value is simply added to the string.)</p><p>The <function>fn:parse-uri</function> function removes
        percent-escaping when it constructs the
        <code nobreak="false">path-segments</code>, <code nobreak="false">query-parameters</code>, and
        <code nobreak="false">fragment</code> properties. That’s often the most
        convenient behavior but, in order to reconstruct a URI from them,
        special escaping rules apply. These rules protect delimiters
        without encoding additional characters unnecessarily.
        The rules for <code nobreak="false">path-segments</code>,
        <code nobreak="false">query-parameters</code>, and <code nobreak="false">fragment</code> are
        slightly different because the URI encoding conventions are
        slightly different in each case.</p><p>An application with more stringent requirements can
        construct a <code nobreak="false">path</code> or <code nobreak="false">query</code> that
        satisfies the requirements and leave the
        <code nobreak="false">path-segments</code> and/or
        <code nobreak="false">query-parameters</code> keys out of the map.</p><ulist><item><p>If the <code nobreak="false">path-segments</code> key exists in
           the map, then the path is constructed from the segments. To
           construct the path, the possibly encoded segments are
           concatentated together, separated by
           <char>U+002F</char> characters.</p><p>The rules for encoding the path segments are different
           for hierarchical and non-hierarchical URIs. If the URI is
           non-hierarchical, no
           encoding is performed on the segments. Otherwise,
           each segment is encoded by replacing any control characters (codepoints less than 0x20)
           and exclusively the following characters with their
           percent-escaped forms: <char>U+0020</char>, <char>U+0025</char>, 
              <char>U+002F</char>, <char>U+003F</char>,
           <char>U+0023</char>, <char>U+002B</char>,
           <char>U+005B</char>, and <char>U+005D</char>. 
              That is “<code nobreak="false">[#0-#20%/\?\#\+\[\]]</code>”.</p><note><p>Encoding is performed unless the URI is known to be non-hierarchical;
              in other words, encoding is the default. This heuristic improves the
              reliability of using <code nobreak="false">fn:build-uri()</code> on the output of
              <code nobreak="false">fn:parse-uri()</code>. (For example,
              <code nobreak="false">fn:parse-uri('a+b/c') =&gt; fn:build-uri()</code> will return 
              <code nobreak="false">a+b/c</code>.)</p><p>It is necessary to avoid encoding non-hierarchical schemes because there is more
              variation in them (for example, the <code nobreak="false">tel:</code> scheme
              uses a “<code nobreak="false">+</code>” that must not be encoded). Users working with
              non-hierarchical schemes may need to address the encoding issue directly
              bearing in mind the encoding requirements of the particular schemes in use.</p></note></item><item><p>Otherwise the value of the <code nobreak="false">path</code> key is used.</p></item><item><p>If neither are present, a zero-length string is used for the path.</p></item></ulist><p>The path is added to the URI.</p><p>If the <code nobreak="false">query-parameters</code> key exists in the map, its value
        must be a map. A sequence of strings is constructed from the values in the map.</p><p>To construct the string, each <emph>key</emph> and <emph>value</emph>
        is encoded.
        The encoding performed replaces any control characters (codepoints less than 0x20)
        and exclusively the following characters with their
        percent-escaped forms: <char>U+0020</char>, <char>U+0025</char>, <char>U+003D</char>,
        <char>U+0026</char>,
        <char>U+0023</char>, <char>U+002B</char>,
        <char>U+005B</char>, and <char>U+005D</char>. That is “<code nobreak="false">[#0-#20%=&amp;\#\+\[\]]</code>”.
        (This differs from the path encoding in that it excludes <char>U+002F</char>
        and <char>U+003F</char> but includes <char>U+003D</char> and <char>U+0026</char>.)
        For each <emph>key</emph> and each <emph>value</emph> associated with
        that key in turn:</p><ulist><item><p>If the <emph>key</emph> is a zero-length string, the string constructed
           is the encoded <emph>value</emph>.</p></item><item><p>Otherwise, the string constructed is the value of the
           <emph>key</emph>, encoded, followed by an equal sign (<char>U+003D</char>),
           followed by the <emph>value</emph>, encoded.</p></item></ulist><p>The query is constructed by joining the resulting
        strings into a single string, separated by <code nobreak="false">&amp;</code> (ampersand) characters.
        If the <code nobreak="false">query-parameters</code> key does not exist in the map, but
        the <code nobreak="false">query</code> key does, then the query is the value of the
        <code nobreak="false">query</code> key.</p><p>If there is a query, it is added to the URI with
        a preceding <char>U+003F</char>.</p><p>If the <code nobreak="false">fragment</code> key exists in the map, then
        the value of that key is encoded and added to the URI with a
        preceding <char>U+0023</char>.

        The encoding performed replaces any control characters (codepoints less than 0x20)
        and exclusively the following characters with their
        percent-escaped forms: <char>U+0020</char>, <char>U+0025</char>,
        <char>U+0023</char>, <char>U+002B</char>,
        <char>U+005B</char>, and <char>U+005D</char>. That is “<code nobreak="false">[#0-#20%\#\+\[\]]</code>”.
        (This differs from the path encoding in that it excludes <char>U+002F</char>
        and <char>U+003F</char>.)</p><p>The resulting URI is returned.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">build-uri({
  "scheme": "https",
  "host": "qt4cg.org",
  "port": (),
  "path": "/specifications/index.html"
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"https://qt4cg.org/specifications/index.html"</eg></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="durations"><head>Processing durations</head><p>Operators are defined on the following type:</p><ulist><item><p><code nobreak="false">xs:duration</code></p></item></ulist><p>and on the two defined subtypes (see <specref ref="duration-subtypes"/>):</p><ulist><item><p><code nobreak="false">xs:yearMonthDuration</code></p></item><item><p><code nobreak="false">xs:dayTimeDuration</code></p></item></ulist><p>Arithmetic on durations is defined only on these subtypes:
               this is because the results of some operations (for example one month minus one day)
               have no representation in the value space.</p><p>Two <code nobreak="false">xs:duration</code> values may however be compared.</p><div2 id="duration-data-types"><head>Duration data types</head><p>A value of type <code nobreak="false">xs:duration</code> is considered to comprise two parts:</p><ulist><item><p>The total number of months, represented as a signed integer.</p></item><item><p>The total number of seconds, represented as a signed decimal number.</p></item></ulist><p>If one of these values is negative (less than zero), the other must not be positive
	        (greater than zero).</p><p>In effect this means that operations on durations (including equality comparison, 
			   casting to string, and extraction of components) 
			   all treat the duration as normalized. The duration <code nobreak="false">PT1M30S</code> (one minute and
			   thirty seconds), for example,
			   is precisely equivalent to the duration <code nobreak="false">PT90S</code> (ninety seconds); these are
			   different representations of the same value, and the result of any operation will be
			   the same regardless which representation is used. For example, the function
			   <function>fn:seconds-from-duration</function> returns 30 in both cases.</p><note><p>The information content of an <code nobreak="false">xs:duration</code>
			value can be reduced to an <code nobreak="false">xs:integer</code> number of months, and an <code nobreak="false">xs:decimal</code>
			number of seconds. For the two defined subtypes this is further simplified so that one of these two
			components is fixed at zero. Operations such as comparison of durations and arithmetic on durations
			can be expressed in terms of numeric operations applied to these two components.</p></note><div3 id="duration-subtypes"><head>Subtypes of duration</head><p>Two subtypes of <code nobreak="false">xs:duration</code>, namely <code nobreak="false">xs:yearMonthDuration</code>
               and <code nobreak="false">xs:dayTimeDuration</code>, are defined in <bibref ref="xmlschema11-2"/>. These types <rfc2119>must</rfc2119>
            be available in the data model whether or not the implementation supports other aspects of XSD 1.1.</p><p>The significance of these subtypes is that arithmetic and ordering become well defined; this is not the
            case for <code nobreak="false">xs:duration</code> values in general, because of the variable number of days in a month. For this reason, many of the functions
            and operators on durations require the arguments/operands to belong to these two subtypes.</p><p>In an <code nobreak="false">xs:yearMonthDuration</code>, the seconds component is always zero. 
            In an <code nobreak="false">xs:dayTimeDuration</code>, the months component is always zero.</p></div3><div3 id="duration-conformance" diff="add" at="issue931"><head>Limits and precision</head><changes><change issue="931" PR="932" date="2024-01-16">
	              The specification now prescribes a minimum precision and range for durations.
	           </change></changes><p>All conforming processors
	           <rfc2119>must</rfc2119>  support duration values in which:</p><ulist><item><p>The total number of months can be represented as a signed <code nobreak="false">xs:int</code> value;</p></item><item><p>The total number of seconds can be represented as a signed <code nobreak="false">xs:decimal</code>
	           value with facets <code nobreak="false">totalDigits=18</code> and <code nobreak="false">fractionalDigits=3</code>. That is,
	           durations must be supported to millisecond precision.</p></item></ulist><p>Processors <rfc2119>may</rfc2119> support a greater range and/or precision.
	           The limits are <termref def="implementation-defined"/>.</p><p>A processor that limits the range or precision of duration values
	           may encounter overflow and underflow conditions when it
	           tries to evaluate operations on durations. In
	           these situations, the processor <rfc2119>must</rfc2119> return a zero-length duration 
	           in case of duration underflow, and <rfc2119>must</rfc2119> raise a dynamic 
	           error <errorref class="DT" code="0001"/> in case of overflow.</p><p>Similarly, a processor may be unable accurately to represent the result of dividing a duration
	        by 2, or multiplying a duration by 0.5. A processor that limits the precision of the seconds component
	        of duration values <rfc2119>must</rfc2119> deliver a result
	        that is as close as possible to the mathematically precise result, given these limits; 
	        if two values are equally close, the one that is chosen is <termref def="implementation-defined"/>.</p></div3></div2><div2 id="comp.duration"><head>Comparing durations</head><p>Duration values may be compared using the <function>fn:compare</function>
		    function.</p><p>In this version of the specification, all <code nobreak="false">xs:duration</code> values
		    are mutually comparable: comparison operations are no longer restricted
		    to the two subtypes <code nobreak="false">xs:yearMonthDuration</code> and <code nobreak="false">xs:dayTimeDuration</code>.
		    However, although a total ordering is defined over all durations, the result
		    is not always meaningful: while it makes sense that <code nobreak="false">P1Y1D</code> (one year and a day)
		    is greater than <code nobreak="false">P1Y</code> (one year), it makes little sense that <code nobreak="false">P32D</code>
		    (thirty-two days) is less than <code nobreak="false">P1M</code> (one month).</p><p>Durations are treated as tuples with two components, the months and seconds
		    components, and they are compared by treating the months as the primary key and the seconds
		    as the primary key.</p></div2><div2 id="component-extraction-durations"><head>Extracting components of durations</head><p>The duration datatype may be considered to be a composite datatype
                    in that it contains distinct properties or components. The extraction functions specified
                    below extract a single component from a duration value. 
For <code nobreak="false">xs:duration</code> and its subtypes, including the two subtypes <code nobreak="false">xs:yearMonthDuration</code> and
 <code nobreak="false">xs:dayTimeDuration</code>, the components are normalized: this means that the seconds and minutes 
 components will always be less than 60, the hours component less than 24, and the months component less than 12.
</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:years-from-duration</code></td><td rowspan="1" colspan="1">Returns the number of years in a duration.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:months-from-duration</code></td><td rowspan="1" colspan="1">Returns the number of months in a duration.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:days-from-duration</code></td><td rowspan="1" colspan="1">Returns the number of days in a duration.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:hours-from-duration</code></td><td rowspan="1" colspan="1">Returns the number of hours in a duration.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:minutes-from-duration</code></td><td rowspan="1" colspan="1">Returns the number of minutes in a duration.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:seconds-from-duration</code></td><td rowspan="1" colspan="1">Returns the number of seconds in a duration.</td></tr></tbody></table><div3 id="func-years-from-duration"><head>fn:years-from-duration</head><glist><gitem><label>Summary</label><def><p>Returns the number of years in a duration.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="years-from-duration" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:duration?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> representing the years
            component in <code nobreak="false">$value</code>. Given that a duration
            is a <code nobreak="false">($months, $seconds)</code> tuple, the result is the value of <code nobreak="false">($months idiv 12)</code>.</p><p>If <code nobreak="false">$value</code> is a negative duration then the result will be negative.</p><p>If <code nobreak="false">$value</code> is an <code nobreak="false">xs:dayTimeDuration</code> the function
            returns <code nobreak="false">0</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">years-from-duration(
  xs:yearMonthDuration("P20Y15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">21</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">years-from-duration(
  xs:yearMonthDuration("-P15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">-1</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">years-from-duration(
  xs:dayTimeDuration("-P2DT15H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">0</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">years-from-duration(
  xs:duration("P1Y1000D")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(To capture whole portions of years reflected in the
                     <code nobreak="false">xs:dayTimeDuration</code> component, it must first be converted to an
                     <code nobreak="false">xs:yearMonthDuration</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-months-from-duration"><head>fn:months-from-duration</head><glist><gitem><label>Summary</label><def><p>Returns the number of months in a duration.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="months-from-duration" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:duration?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> representing the months
            component in <code nobreak="false">$value</code>. Given that a duration
               is a <code nobreak="false">($months, $seconds)</code> tuple, the result is the value of <code nobreak="false">($months mod 12)</code>.</p><p>If <code nobreak="false">$value</code> is a negative duration then the result will be negative.</p><p>If <code nobreak="false">$value</code> is an <code nobreak="false">xs:dayTimeDuration</code> the function
            returns <code nobreak="false">0</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">months-from-duration(
  xs:yearMonthDuration("P20Y15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">3</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">months-from-duration(
  xs:yearMonthDuration("-P20Y18M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">-6</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">months-from-duration(
  xs:dayTimeDuration("-P2DT15H0M0S")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">0</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">months-from-duration(
   xs:duration("P1M100D")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(To capture whole portions of months reflected in the
                     <code nobreak="false">xs:dayTimeDuration</code> component, it must first be converted to an
                     <code nobreak="false">xs:yearMonthDuration</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-days-from-duration"><head>fn:days-from-duration</head><glist><gitem><label>Summary</label><def><p>Returns the number of days in a duration.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="days-from-duration" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:duration?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> representing the days
            component in <code nobreak="false">$value</code>. Given that a duration
               is a <code nobreak="false">($months, $seconds)</code> tuple, the result is <code nobreak="false">($seconds idiv 86400)</code>.</p><p>If <code nobreak="false">$value</code> is a negative duration then the result will be negative.</p><p>If <code nobreak="false">$value</code> is an <code nobreak="false">xs:yearMonthDuration</code> the function returns <code nobreak="false">0</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">days-from-duration(
  xs:dayTimeDuration("P3DT10H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">3</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">days-from-duration(
  xs:dayTimeDuration("P3DT55H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">5</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">days-from-duration(
  xs:yearMonthDuration("P3Y5M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">0</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">days-from-duration(
   xs:duration("P1Y1D")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(To capture days reflected in the <code nobreak="false">xs:yearMonthDuration</code>
                  component, it must first be converted to an
                  <code nobreak="false">xs:dayTimeDuration</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-hours-from-duration"><head>fn:hours-from-duration</head><glist><gitem><label>Summary</label><def><p>Returns the number of hours in a duration.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="hours-from-duration" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:duration?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> representing the hours
            component in <code nobreak="false">$value</code>. <phrase>Given that a duration
               is a <code nobreak="false">($months, $seconds)</code> tuple, the result is the value of <code nobreak="false">($seconds mod 86400) idiv 3600</code></phrase>.</p><p>If <code nobreak="false">$value</code> is a negative duration then the result will be negative.</p><p>If <code nobreak="false">$value</code> is an <code nobreak="false">xs:yearMonthDuration</code> the function returns <code nobreak="false">0</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-duration(
  xs:dayTimeDuration("P3DT10H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">10</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-duration(
  xs:dayTimeDuration("P3DT12H32M12S")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">12</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-duration(
  xs:dayTimeDuration("PT123H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">3</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-duration(
  xs:dayTimeDuration("-P3DT10H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">-10</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-duration(
   xs:duration("P1YT1H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(To capture hours reflected in the <code nobreak="false">xs:yearMonthDuration</code>
                  component, it must first be converted to an
                  <code nobreak="false">xs:dayTimeDuration</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-minutes-from-duration"><head>fn:minutes-from-duration</head><glist><gitem><label>Summary</label><def><p>Returns the number of minutes in a duration.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="minutes-from-duration" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:duration?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> representing the minutes
            component in  <code nobreak="false">$value</code>. Given that a duration
               is a <code nobreak="false">($months, $seconds)</code> tuple, the result is the value of <code nobreak="false">($seconds mod 3600) idiv 60</code>.</p><p>If <code nobreak="false">$value</code> is a negative duration then the result will be negative.</p><p>If <code nobreak="false">$value</code> is an <code nobreak="false">xs:yearMonthDuration</code> the function returns <code nobreak="false">0</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">minutes-from-duration(
  xs:dayTimeDuration("P3DT10H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">0</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">minutes-from-duration(
  xs:dayTimeDuration("-P5DT12H30M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">-30</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">minutes-from-duration(
   xs:duration("P1YT1M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(To capture minutes reflected in the <code nobreak="false">xs:yearMonthDuration</code>
                  component, it must first be converted to an
                  <code nobreak="false">xs:dayTimeDuration</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-seconds-from-duration"><head>fn:seconds-from-duration</head><glist><gitem><label>Summary</label><def><p>Returns the number of seconds in a duration.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="seconds-from-duration" return-type="xs:decimal?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:duration?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:decimal</code> representing the seconds
            component in <code nobreak="false">$value</code>. Given that a duration
               is a <code nobreak="false">($months, $seconds)</code> tuple, the result is the value of <code nobreak="false">($seconds mod 60)</code>
            as an <code nobreak="false">xs:decimal</code>.</p><p>If <code nobreak="false">$value</code> is a negative duration then the result will be negative.</p><p>If <code nobreak="false">$value</code> is an <code nobreak="false">xs:yearMonthDuration</code> the function returns <code nobreak="false">0</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds-from-duration(
  xs:dayTimeDuration("P3DT10H12.5S")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">12.5</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds-from-duration(
  xs:dayTimeDuration("-PT256S")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">-16.0</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds-from-duration(
   xs:duration("P1YT1S")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(To capture seconds reflected in the <code nobreak="false">xs:yearMonthDuration</code>
                  component of an <code nobreak="false">xs:duration</code>, it must first be converted to an
                  <code nobreak="false">xs:dayTimeDuration</code>.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds-from-duration(
   xs:duration("P1YT1S")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(To capture seconds reflected in the <code nobreak="false">xs:yearMonthDuration</code>
                  component, it must first be converted to an
                  <code nobreak="false">xs:dayTimeDuration</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="duration-construction"><head>Constructing durations</head><p>This section decribes the <function>fn:seconds</function> function, which constructs
	        an <code nobreak="false">xs:dayTimeDuration</code> value representing a decimal number of seconds.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:seconds</code></td><td rowspan="1" colspan="1">Returns an <code nobreak="false">xs:dayTimeDuration</code> whose length is a given number of seconds.</td></tr></tbody></table><div3 id="func-seconds"><head>fn:seconds</head><changes><change issue="959" PR="984" date="2024-02-06">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns an <code nobreak="false">xs:dayTimeDuration</code> whose length is a given number of seconds.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="seconds" return-type="xs:dayTimeDuration?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:decimal?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:dayTimeDuration</code> value whose length
            in seconds is equal to <code nobreak="false">$value</code>. </p><p>If <code nobreak="false">$value</code> is negative then the result will be a negative duration.</p><p>For handling of overflow and underflow, see <specref ref="duration-limits"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The result of <code nobreak="false">seconds($n)</code> is approximately equal to the result of
         the expression <code nobreak="false">xs:dayTimeDuration('PT1S') * $n</code>. The equivalence is only
         approximate, because <code nobreak="false">seconds($n)</code> uses the exact <code nobreak="false">xs:decimal</code>
         value supplied, whereas multiplying a duration by a number first converts the number
         to an <code nobreak="false">xs:double</code> value, which may lose precision.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds(1)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('PT1S')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds(0.001)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('PT0.001S')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds(60)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('PT1M')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds(86400)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('P1D')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds(-5400)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('-PT1H30M')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('1970-01-01T00:00:00Z') + 1706702400 * seconds(1)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2024-01-31T12:00:00Z')</eg><p><emph>(The expression converts a Unix timestamp to an <code nobreak="false">xs:dateTime</code> value).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">(
  xs:dateTime('2024-01-31T12:00:00Z') -
  xs:dateTime('1970-01-01T00:00:00Z')
) div seconds(1)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1706702400</eg><p><emph>(The expression converts an <code nobreak="false">xs:dateTime</code> value to a Unix timestamp).</emph></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="duration-arithmetic"><head>Arithmetic operators on durations</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:add-yearMonthDurations</code></td><td rowspan="1" colspan="1">Returns the result of adding two <code nobreak="false">xs:yearMonthDuration</code> values. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-yearMonthDurations</code></td><td rowspan="1" colspan="1">Returns the result of subtracting one <code nobreak="false">xs:yearMonthDuration</code> value from
            another. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:multiply-yearMonthDuration</code></td><td rowspan="1" colspan="1">Returns the result of multiplying  <code nobreak="false">$arg1</code> by <code nobreak="false">$arg2</code>.
            The result is rounded to the nearest month.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:divide-yearMonthDuration</code></td><td rowspan="1" colspan="1">Returns the result of dividing <code nobreak="false">$arg1</code> by <code nobreak="false">$arg2</code>.
            The result is rounded to the nearest month.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:divide-yearMonthDuration-by-yearMonthDuration</code></td><td rowspan="1" colspan="1">Returns the ratio of two <code nobreak="false">xs:yearMonthDuration</code> values.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:add-dayTimeDurations</code></td><td rowspan="1" colspan="1">Returns the sum of two <code nobreak="false">xs:dayTimeDuration</code> values.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-dayTimeDurations</code></td><td rowspan="1" colspan="1">Returns the result of subtracting one <code nobreak="false">xs:dayTimeDuration</code> from another.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:multiply-dayTimeDuration</code></td><td rowspan="1" colspan="1">Returns the result of multiplying a <code nobreak="false">xs:dayTimeDuration</code> by a number.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:divide-dayTimeDuration</code></td><td rowspan="1" colspan="1">Returns the result of multiplying a <code nobreak="false">xs:dayTimeDuration</code> by a number.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:divide-dayTimeDuration-by-dayTimeDuration</code></td><td rowspan="1" colspan="1">Returns the ratio of two <code nobreak="false">xs:dayTimeDuration</code> values, as a decimal
            number.</td></tr></tbody></table><p>For operators that combine a duration and a date/time value, see <specref ref="dateTime-arithmetic"/>.</p><div3 id="func-add-yearMonthDurations"><head>op:add-yearMonthDurations</head><glist><gitem><label>Summary</label><def><p>Returns the result of adding two <code nobreak="false">xs:yearMonthDuration</code> values. </p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the
         <code nobreak="false">+</code> operator when applied to two <code nobreak="false">xs:yearMonthDuration</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="add-yearMonthDurations" return-type="xs:yearMonthDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:yearMonthDuration"/><arg name="arg2" type="xs:yearMonthDuration"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of adding <code nobreak="false">$arg1</code> to <code nobreak="false">$arg2</code>. 
            The result will be an <code nobreak="false">xs:yearMonthDuration</code> whose
            length in months is equal to the length in months of <code nobreak="false">$arg1</code> plus the length
            in months of <code nobreak="false">$arg2</code>.</p><p>For handling of overflow, see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either duration (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:add-yearMonthDurations(
  xs:yearMonthDuration("P2Y11M"),
  xs:yearMonthDuration("P3Y3M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:yearMonthDuration("P6Y2M")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-yearMonthDurations"><head>op:subtract-yearMonthDurations</head><glist><gitem><label>Summary</label><def><p>Returns the result of subtracting one <code nobreak="false">xs:yearMonthDuration</code> value from
            another. </p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the
         <code nobreak="false">-</code> operator when applied to two <code nobreak="false">xs:yearMonthDuration</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-yearMonthDurations" return-type="xs:yearMonthDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:yearMonthDuration"/><arg name="arg2" type="xs:yearMonthDuration"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of subtracting <code nobreak="false">$arg2</code> from 
            <code nobreak="false">$arg1</code>. The result will be an <code nobreak="false">xs:yearMonthDuration</code>
            whose length in months is equal to the length in months of <code nobreak="false">$arg1</code> minus the
            length in months of <code nobreak="false">$arg2</code>.</p><p>For handling of overflow, see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either duration (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-yearMonthDurations(
  xs:yearMonthDuration("P2Y11M"),
  xs:yearMonthDuration("P3Y3M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:yearMonthDuration("-P4M")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-multiply-yearMonthDuration"><head>op:multiply-yearMonthDuration</head><glist><gitem><label>Summary</label><def><p>Returns the result of multiplying  <code nobreak="false">$arg1</code> by <code nobreak="false">$arg2</code>.
            The result is rounded to the nearest month.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the
         <code nobreak="false">*</code> operator when applied to an <code nobreak="false">xs:yearMonthDuration</code> and a numeric
         value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="multiply-yearMonthDuration" return-type="xs:yearMonthDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:yearMonthDuration"/><arg name="arg2" type="xs:double"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The result is the <code nobreak="false">xs:yearMonthDuration</code> whose length in months is equal to
            the result of applying the <function>fn:round</function> function to the value obtained by
            multiplying the length in months of <code nobreak="false">$arg1</code> by the value of
               <code nobreak="false">$arg2</code>.</p><p>If <code nobreak="false">$arg2</code> is positive or negative zero, the result is a zero-length
            duration. If <code nobreak="false">$arg2</code> is positive or negative infinity, the result overflows
            and is handled as described in <specref ref="duration-limits"/>. </p><p>For handling of overflow, underflow, and rounding, see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="CA" code="0005"/> if <code nobreak="false">$arg2</code> is
               <code nobreak="false">NaN</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either duration (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:multiply-yearMonthDuration(
  xs:yearMonthDuration("P2Y11M"),
  2.3
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:yearMonthDuration("P6Y9M")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-divide-yearMonthDuration"><head>op:divide-yearMonthDuration</head><glist><gitem><label>Summary</label><def><p>Returns the result of dividing <code nobreak="false">$arg1</code> by <code nobreak="false">$arg2</code>.
            The result is rounded to the nearest month.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the
         <code nobreak="false">div</code> operator when applied to an <code nobreak="false">xs:yearMonthDuration</code> and a numeric
         value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="divide-yearMonthDuration" return-type="xs:yearMonthDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:yearMonthDuration"/><arg name="arg2" type="xs:double"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The result is the <code nobreak="false">xs:yearMonthDuration</code> whose length in months is equal to
            the result of applying the <function>fn:round</function> function to the value obtained by
            dividing the length in months of <code nobreak="false">$arg1</code> by the value of
            <code nobreak="false">$arg2</code>.</p><p>If <code nobreak="false">$arg2</code> is positive or negative infinity, the result is a zero-length
            duration. If <code nobreak="false">$arg2</code> is positive or negative zero, the result overflows and
            is handled as described in <specref ref="duration-limits"/>. </p><p>For handling of overflow, underflow, and rounding, 
            see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="CA" code="0005"/> if <code nobreak="false">$arg2</code> is
               <code nobreak="false">NaN</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either operand (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:divide-yearMonthDuration(
  xs:yearMonthDuration("P2Y11M"),
  1.5
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:yearMonthDuration("P1Y11M")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-divide-yearMonthDuration-by-yearMonthDuration"><head>op:divide-yearMonthDuration-by-yearMonthDuration</head><glist><gitem><label>Summary</label><def><p>Returns the ratio of two <code nobreak="false">xs:yearMonthDuration</code> values.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the
         <code nobreak="false">div</code> operator when applied to two <code nobreak="false">xs:yearMonthDuration</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="divide-yearMonthDuration-by-yearMonthDuration" return-type="xs:decimal" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:yearMonthDuration"/><arg name="arg2" type="xs:yearMonthDuration"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of dividing the length in months of <code nobreak="false">$arg1</code>
            by the length in months of <code nobreak="false">$arg2</code>, according to the rules of the
               <code nobreak="false">op:numeric-divide</code> function for integer operands.</p><p>For handling of overflow, underflow, and rounding, 
            see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either duration (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:divide-yearMonthDuration-by-yearMonthDuration(
  xs:yearMonthDuration("P3Y4M"),
  xs:yearMonthDuration("-P1Y4M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">-2.5</eg></td></tr><tr><td colspan="2" rowspan="1"><p>The following example demonstrates how to calculate the length of an
                  <code nobreak="false">xs:yearMonthDuration</code> value in months:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:divide-yearMonthDuration-by-yearMonthDuration(
  xs:yearMonthDuration("P3Y4M"),
  xs:yearMonthDuration("P1M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">40</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-add-dayTimeDurations"><head>op:add-dayTimeDurations</head><glist><gitem><label>Summary</label><def><p>Returns the sum of two <code nobreak="false">xs:dayTimeDuration</code> values.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">+</code>
         operator when applied to two <code nobreak="false">xs:dayTimeDuration</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="add-dayTimeDurations" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dayTimeDuration"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of adding <code nobreak="false">$arg1</code> to 
            <code nobreak="false">$arg2</code>. The result is the <code nobreak="false">xs:dayTimeDuration</code> whose length in
            seconds is equal to the sum of the length in seconds of the two input durations.</p><p>For handling of overflow, see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either duration (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:add-dayTimeDurations(
  xs:dayTimeDuration("P2DT12H5M"),
  xs:dayTimeDuration("P5DT12H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('P8DT5M')</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-dayTimeDurations"><head>op:subtract-dayTimeDurations</head><glist><gitem><label>Summary</label><def><p>Returns the result of subtracting one <code nobreak="false">xs:dayTimeDuration</code> from another.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">-</code>
         operator when applied to two <code nobreak="false">xs:dayTimeDuration</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-dayTimeDurations" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dayTimeDuration"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of subtracting <code nobreak="false">$arg2</code> from 
            <code nobreak="false">$arg1</code>. The result is the <code nobreak="false">xs:dayTimeDuration</code> whose
            length in seconds is equal to the length in seconds of <code nobreak="false">$arg1</code> minus the
            length in seconds of <code nobreak="false">$arg2</code>.</p><p>For handling of overflow, see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either duration (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dayTimeDurations(
  xs:dayTimeDuration("P2DT12H"),
  xs:dayTimeDuration("P1DT10H30M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('P1DT1H30M')</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-multiply-dayTimeDuration"><head>op:multiply-dayTimeDuration</head><glist><gitem><label>Summary</label><def><p>Returns the result of multiplying a <code nobreak="false">xs:dayTimeDuration</code> by a number.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">*</code>
         operator when applied to an <code nobreak="false">xs:dayTimeDuration</code> and a numeric
         value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="multiply-dayTimeDuration" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dayTimeDuration"/><arg name="arg2" type="xs:double"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of multiplying <code nobreak="false">$arg1</code> by
               <code nobreak="false">$arg2</code>. The result is the <code nobreak="false">xs:dayTimeDuration</code> whose length in
            seconds is equal to the length in seconds of <code nobreak="false">$arg1</code> multiplied by the
            numeric value <code nobreak="false">$arg2</code>.</p><p>If <code nobreak="false">$arg2</code> is positive or negative zero, the result is a zero-length
            duration. If <code nobreak="false">$arg2</code> is positive or negative infinity, the result overflows
            and is handled as described in <specref ref="duration-conformance"/>. </p><p>For handling of overflow, underflow, and rounding, see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="CA" code="0005"/> if <code nobreak="false">$arg2</code> is
               <code nobreak="false">NaN</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either operand (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:multiply-dayTimeDuration(
  xs:dayTimeDuration("PT2H10M"),
  2.1
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('PT4H33M')</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-divide-dayTimeDuration"><head>op:divide-dayTimeDuration</head><glist><gitem><label>Summary</label><def><p>Returns the result of multiplying a <code nobreak="false">xs:dayTimeDuration</code> by a number.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the
         <code nobreak="false">div</code> operator when applied to two <code nobreak="false">xs:dayTimeDuration</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="divide-dayTimeDuration" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dayTimeDuration"/><arg name="arg2" type="xs:double"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of dividing <code nobreak="false">$arg1</code> by
               <code nobreak="false">$arg2</code>. The result is the <code nobreak="false">xs:dayTimeDuration</code> whose length in
            seconds is equal to the length in seconds of <code nobreak="false">$arg1</code> divided by the numeric
            value <code nobreak="false">$arg2</code>.</p><p>If <code nobreak="false">$arg2</code> is positive or negative infinity, the result is a zero-length
            duration. If <code nobreak="false">$arg2</code> is positive or negative zero, the result overflows and
            is handled as described in <specref ref="duration-conformance"/>. </p><p>For handling of overflow, underflow, and rounding, see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="CA" code="0005"/> if <code nobreak="false">$arg2</code> is
               <code nobreak="false">NaN</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either operand (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:divide-dayTimeDuration(
  xs:dayTimeDuration("P1DT2H30M10.5S"),
  1.5
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:duration("PT17H40M7S")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-divide-dayTimeDuration-by-dayTimeDuration"><head>op:divide-dayTimeDuration-by-dayTimeDuration</head><glist><gitem><label>Summary</label><def><p>Returns the ratio of two <code nobreak="false">xs:dayTimeDuration</code> values, as a decimal
            number.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the
         <code nobreak="false">div</code> operator when applied to two <code nobreak="false">xs:dayTimeDuration</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="divide-dayTimeDuration-by-dayTimeDuration" return-type="xs:decimal" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dayTimeDuration"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of dividing <code nobreak="false">$arg1</code> by
               <code nobreak="false">$arg2</code>. The result is the <code nobreak="false">xs:dayTimeDuration</code> whose length in
            seconds is equal to the length in seconds of <code nobreak="false">$arg1</code> divided by the length in
            seconds of <code nobreak="false">$arg2</code>. The calculation is performed by applying
               <code nobreak="false">op:numeric-divide</code> to the two <code nobreak="false">xs:decimal</code> operands.</p><p>For handling of overflow, underflow, and rounding, 
            see <specref ref="duration-conformance"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Either operand (and therefore the result) may be negative.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">round-half-to-even(
  op:divide-dayTimeDuration-by-dayTimeDuration(
    xs:dayTimeDuration("P2DT53M11S"), xs:dayTimeDuration("P1DT10H")
  ),
  4
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1.4378</eg></td></tr><tr><td colspan="2" rowspan="1"><p>This examples shows how to determine the number of seconds in a duration.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:divide-dayTimeDuration-by-dayTimeDuration(
  xs:dayTimeDuration("P2DT53M11S"),
  seconds(1)
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">175991.0</eg></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="dates-times"><head>Processing dates and times</head><p>This section defines operations on the <bibref ref="xmlschema-2"/> date and time types.</p><p>
See <bibref ref="Working-With-Timezones"/> for a disquisition on working with date and time values with and without timezones.
</p><div2 id="date-time-types"><head>Date and time types</head><changes><change issue="2520">The semantics of date/time operations are now based on the definitions
               in XSD 1.1, although validation may still use an XSD 1.0 schema processor.</change></changes><p><termdef id="dt-gregorian" term="Gregorian">The eight primitive types 
            <code nobreak="false">xs:dateTime</code>, <code nobreak="false">xs:date</code>, <code nobreak="false">xs:time</code>, <code nobreak="false">xs:gYearMonth</code>, 
               <code nobreak="false">xs:gYear</code>, <code nobreak="false">xs:gMonthDay</code>, <code nobreak="false">xs:gMonth</code>, <code nobreak="false">xs:gDay</code>
            are referred to collectively as the <term>Gregorian</term> types.</termdef></p><p>This section describes operations on atomic items of these types.</p><p>Values of these types are modeled as comprising one or more of the seven components
            year, month, day, hour, minute, second, and timezone.</p><p>The only operations defined on					
                    <code nobreak="false">xs:gYearMonth</code>, <code nobreak="false">xs:gYear</code>,
                    <code nobreak="false">xs:gMonthDay</code>, <code nobreak="false">xs:gMonth</code>, and <code nobreak="false">xs:gDay</code> values are 
               equality comparison, ordering, and component extraction.
               For other types, further operations are provided, including  
               arithmetic, formatted display, and timezone
					adjustment.</p><div3 id="date-time-duration-conformance"><head>Limits and precision</head><p>All conforming processors
                        <rfc2119>must</rfc2119> support
                        and a minimum fractional second precision of 1 millisecond or three
                        digits (that is, <code nobreak="false">s.sss</code>). However, processors
                        <rfc2119>may</rfc2119> support a higher <termref def="implementation-defined"/> precision.</p><p>All conforming processors
                        <rfc2119>must</rfc2119> support year values in the range 1 to 9999.
                        Processors <rfc2119>may</rfc2119> support a larger range than this.
                  If the supported range includes negative years, then it must also include the year zero.
                  Arithmetic on dates works on the basis of the proleptic Gregorian calendar, as defined
                  in ISO 8601, in which the year preceding 0001 CE is numbered zero.</p><p>In XSD 1.0, dates can include a negative year, but cannot include the year zero.
               In the 4.0 version of this specification, the value space includes values with year zero,
               and casting from <code nobreak="false">xs:string</code> accepts year zero in the lexical representation.
               If an XSD 1.0 processor is used to validate source documents containing dates with negative
               years, then it is <termref def="implementation-defined"/> whether the lexical
               form <code nobreak="false">-0001</code> translates to year zero or year -1 in the value space.</p><p>A processor that limits the number of digits in date and time datatype
                        representations may encounter overflow and underflow conditions when it
                        tries to execute the functions in <specref ref="dateTime-arithmetic"/>. In
                        these situations, the processor <rfc2119>must</rfc2119> return 00:00:00 in case of time underflow.
                  It <rfc2119>must</rfc2119> raise a dynamic 
                  error <errorref class="DT" code="0001"/> in case of overflow.</p><p>Similarly, a processor that limits the precision of the seconds component
                  of date and time or duration values may need to deliver a rounded result for arithmetic operations.  
                  Such a processor <rfc2119>must</rfc2119> deliver a result
                  that is as close as possible to the mathematically precise result, given these limits: 
                  if two values are equally close, the one that is chosen is 
                  <termref def="implementation-defined"/>.</p></div3></div2><div2 id="date-time-values"><head>Date/time datatype values</head><p>As defined in <xspecref spec="DM31" ref="dates-and-times"/>, <code nobreak="false">xs:dateTime</code>, 
			<code nobreak="false">xs:date</code>, <code nobreak="false">xs:time</code>,  <code nobreak="false">xs:gYearMonth</code>, <code nobreak="false">xs:gYear</code>, 
			<code nobreak="false">xs:gMonthDay</code>, <code nobreak="false">xs:gMonth</code>, <code nobreak="false">xs:gDay</code> values, 
			referred to collectively as <termref def="dt-gregorian"/> values, are represented as seven components or properties: 

			<code nobreak="false">year</code>, <code nobreak="false">month</code>, <code nobreak="false">day</code>, <code nobreak="false">hours</code>, <code nobreak="false">minutes</code>, 
			<code nobreak="false">seconds</code> and <code nobreak="false">timezone</code>.  The first five components are 
			<code nobreak="false">xs:integer</code> values.  The value of the <code nobreak="false">seconds</code> component is an <code nobreak="false">xs:decimal</code>
			and the value of the <code nobreak="false">timezone</code> component is an <code nobreak="false">xs:dayTimeDuration</code>.  
			For all the primitive date/time datatypes, the <code nobreak="false">timezone</code> property is optional and may or may not 
			be present. Depending on the datatype, some of the remaining six properties must be present and 
			some must be <xtermref ref="dt-absent" spec="DM31">absent</xtermref>.   
               Absent, or missing, properties are represented by the empty sequence.</p><p><termdef id="dt-local-gregorian" term="local gregorian">A <termref def="dt-gregorian"/> value that includes
         a timezone component is referred to as a <term>local gregorian</term> value.</termdef></p><p><termdef id="dt-normalized-gregorian" term="normalized-gregorian">A <termref def="dt-gregorian"/>
         value in which the timezone offset is zero (that is, UTC) is referred to as a <term>normalized gregorian</term>
         value.</termdef>. For every <termref def="dt-local-gregorian"/> value, there is an equivalent
         normalized gregorian value representing the same point in time, but in the UTC timezone. Operations
         that compare or subtract <termref def="dt-gregorian"/> values always work on normalized values.</p><p>For <code nobreak="false">xs:time</code>, <code nobreak="false">00:00:00</code> and <code nobreak="false">24:00:00</code> are alternate lexical forms 
			for the same value, whose canonical representation is <code nobreak="false">00:00:00</code>.  For <code nobreak="false">xs:dateTime</code>,
		    a time component <code nobreak="false">24:00:00</code> translates to <code nobreak="false">00:00:00</code> of the following day.</p><div3 id="date-time-lexical-mapping"><head>Examples</head><ulist><item><p>An <code nobreak="false">xs:dateTime</code> with lexical
                        representation <code nobreak="false">1999-05-31T05:00:00</code>
						is represented in the datamodel by <code nobreak="false">{ 1999, 5, 31, 5, 0, 0.0, () }</code>.</p></item><item><p>An <code nobreak="false">xs:dateTime</code> with lexical
                        representation <code nobreak="false">1999-05-31T13:20:00-05:00</code> 
                  is represented by <code nobreak="false">{ 1999, 5, 31, 13, 20, 0.0, xs:dayTimeDuration("-PT5H") }</code>.</p></item><item><p>An <code nobreak="false">xs:dateTime</code> with lexical
                        representation <code nobreak="false">1999-12-31T24:00:00</code> 
						is represented by <code nobreak="false">{ 2000, 1, 1, 0, 0, 0.0, () }</code>.</p></item><item><p>An <code nobreak="false">xs:date</code> with lexical
                        representation <code nobreak="false">2005-02-28+8:00</code> 
						is represented by <code nobreak="false">{ 2005, 2, 28, (), (), (), xs:dayTimeDuration("PT8H") }</code>.</p></item><item><p>An <code nobreak="false">xs:time</code> with lexical
                        representation <code nobreak="false">24:00:00</code> 
						is represented by <code nobreak="false">{ (), (), (), 0, 0, 0, () }</code>.</p></item></ulist></div3></div2><div2 id="dateTime-record"><head>Record fn:dateTime-record</head><p>This record type is used to represent the components of a value of type <code nobreak="false">xs:dateTime</code>,
            <code nobreak="false">xs:date</code>, <code nobreak="false">xs:time</code>, <code nobreak="false">xs:gYear</code>, <code nobreak="false">xs:gYearMonth</code>,
            <code nobreak="false">xs:gMonth</code>, <code nobreak="false">xs:gMonthDay</code>, or <code nobreak="false">xs:gDay</code>.</p><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Name</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">year?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The value of the <code nobreak="false">year</code> component. Range is implementation-defined.
            If years less than one are supported, then the integer zero represents the year
            before year one, and the integer -1 represents the year before year zero.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:integer</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">month?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The value of the <code nobreak="false">month</code> component. A valid value is in the range 1 to 12 inclusive.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:integer</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">day?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The value of the <code nobreak="false">day</code> component. A valid value is in the range 1 to 31 inclusive.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:integer</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">hours?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The value of the <code nobreak="false">hours</code> component. A valid value is in the range 0 to 23 inclusive.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:integer</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">minutes?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The value of the <code nobreak="false">minutes</code> component. A valid value is in the range 0 to 59 inclusive.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:integer</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">seconds?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The value of the <code nobreak="false">seconds</code> component. A valid value is in the range 0 (inclusive) to 60 (exclusive).</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:decimal</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">timezone?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The timezone offset, if the value has a timezone. A valid value corresponds to an integral number
            of minutes between -840 and +840 inclusive.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:dayTimeDuration</code></p></item></ulist></td></tr></tbody></table><note><p>Not every instance of the type <code nobreak="false">fn:dateTime-record</code> represents
               a valid <termref def="dt-gregorian"/> value. Examples of values that match
               the record type but do not represent valid <termref def="dt-gregorian"/> values
               include:</p><ulist><item><p><code nobreak="false">{"month": 0}</code> (the value is out of range)</p></item><item><p><code nobreak="false">{"month": 4, "day": 31}</code> (April has only 30 days)</p></item><item><p><code nobreak="false">{"hours": 24, "minutes": 0, "seconds": 0}</code> (midnight is
                  represented with <code nobreak="false">hours=0</code>)</p></item><item><p><code nobreak="false">{"year": 1900, "day": 1}</code> (<code nobreak="false">year</code> and <code nobreak="false">day</code>, 
                        with no <code nobreak="false">month</code>, is not a valid combination)</p></item><item><p><code nobreak="false">{"year": 1900, "timezone": xs:dayTimeDuration("PT24H")</code> (timezones
                  must be an integral number of minutes between -840 and +840 inclusive)</p></item></ulist><p>It is possible to construct an instance of <code nobreak="false">fn:dateTime-record</code> that does
               not satisfy these constraints, but it will be rejected if used as an argument to
               <function>fn:build-dateTime</function>.</p></note></div2><div2 id="constructing-dateTime"><head>Constructing a dateTime</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:dateTime</code></td><td rowspan="1" colspan="1">Returns an <code nobreak="false">xs:dateTime</code> value created by combining an <code nobreak="false">xs:date</code>
            and an <code nobreak="false">xs:time</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:build-dateTime</code></td><td rowspan="1" colspan="1">Constructs a <termref def="dt-gregorian"/> value from the values of its components.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:unix-dateTime</code></td><td rowspan="1" colspan="1">Returns a dateTime value for a Unix time.</td></tr></tbody></table><div3 id="func-dateTime"><head>fn:dateTime</head><glist><gitem><label>Summary</label><def><p>Returns an <code nobreak="false">xs:dateTime</code> value created by combining an <code nobreak="false">xs:date</code>
            and an <code nobreak="false">xs:time</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="dateTime" return-type="xs:dateTime?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="date" type="xs:date?"/><arg name="time" type="xs:time?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If either <code nobreak="false">$date</code> or <code nobreak="false">$time</code> is the empty sequence, the function
            returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:dateTime</code> whose date component is
            equal to <code nobreak="false">$date</code> and whose time component is equal to <code nobreak="false">$time</code>.</p><p>The timezone of the result is computed as follows:</p><ulist><item><p>If neither argument has a timezone, the result has no timezone.</p></item><item><p>If exactly one of the arguments has a timezone, or if both arguments have the same
                  timezone, the result has this timezone.</p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="RG" code="0008"/> if the two arguments both
            have timezones and the timezones are different. </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">dateTime(
  xs:date("1999-12-31"),
  xs:time("12:00:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime("1999-12-31T12:00:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">dateTime(
  xs:date("1999-12-31"),
  xs:time("24:00:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime("1999-12-31T00:00:00")</eg><p><emph>(This is because <code nobreak="false">"24:00:00"</code> is an alternate lexical form
                  for <code nobreak="false">"00:00:00"</code>).</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-build-dateTime"><head>fn:build-dateTime</head><changes><change>New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Constructs a <termref def="dt-gregorian"/> value from the values of its components.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="build-dateTime" return-type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type-ref="dateTime-record" type-ref-occurs="?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns a <termref def="dt-gregorian"/> value based on the supplied component
            values. The result will be the <termref def="dt-gregorian"/> value <code nobreak="false">$R</code> such that
            <code nobreak="false">deep-equal( $significant(parts-of-dateTime($R)), $significant($value) )</code>,
            where <code nobreak="false">$significant</code> is the function <code nobreak="false">map:filter(?, fn($K, $V){$K eq "timezone" or exists($V)})</code>,
         that is, a function that discards entries in a map whose value is the empty sequence, other than the entry
         with key <code nobreak="false">"timezone"</code>.</p><p>If all seven components are present (year, month, day, hours, minutes, seconds, and timezone)
         then the result will be of type <code nobreak="false">xs:dateTimeStamp</code>.</p><p>The range of years supported is <termref def="implementation-defined"/>. If years earlier than
         0001 CE are supported then the numbering follows the proleptic Gregorian calendar as defined
         in ISO 8601. This means that the year before 0001 CE is numbered zero, and the year before that
         is numbered -1.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DT" code="0005"/> if the set of fields
         that are present and non-empty in <code nobreak="false">$value</code> is not one of the sets:</p><ulist><item><p>year, month, day, hours, minutes, seconds, and optional timezone (delivering an <code nobreak="false">xs:dateTime</code>)</p></item><item><p>year, month, day, and optional timezone (delivering an <code nobreak="false">xs:date</code>)</p></item><item><p>year, and optional timezone (delivering an <code nobreak="false">xs:gYear</code>)</p></item><item><p>year, month, and optional timezone (delivering an <code nobreak="false">xs:gYearMonth</code>)</p></item><item><p>month, and optional timezone (delivering an <code nobreak="false">xs:gMonth</code>)</p></item><item><p>month, day, and optional timezone (delivering an <code nobreak="false">xs:gMonthDay</code>)</p></item><item><p>day, and optional timezone (delivering an <code nobreak="false">xs:gDay</code>)</p></item><item><p>hours, minutes, seconds, and optional timezone (delivering an <code nobreak="false">xs:time</code>)</p></item></ulist><p>A dynamic error is raised <errorref class="DT" code="0006"/> if any of the
            components in <code nobreak="false">$value</code> is outside the permitted range
            (for example if the value of the <code nobreak="false">minutes</code> component is less than zero or
            greater than 59, or if the timezone is outside the range <code nobreak="false">-PT14H</code> to <code nobreak="false">PT14H</code>), 
            or if the combination of fields is not a valid date/time (for example,
            if <code nobreak="false">month</code> is 4 and <code nobreak="false">day</code> is 31).</p></def></gitem><gitem><label>Notes</label><def><note><p>Components that are present in <code nobreak="false">$value</code> but with an empty value are treated
         as if they were absent.</p><p>The timezone, if present, must correspond to an integral number of minutes in the range
         -840 to +840.</p><p>Midnight must be expressed with the <code nobreak="false">hours</code> value set to zero, not 24.</p><p>The standard <xtermref spec="XP40" ref="dt-coercion-rules"/> apply, so (for example) the integral 
         components may be supplied as <code nobreak="false">xs:double</code> values, and the timezone may be
         supplied as an <code nobreak="false">xs:duration</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
build-dateTime({
  "year": 1999,
  "month": 5,
  "day": 31, 
  "hours": 13,
  "minutes": 20,
  "seconds": 0, 
  "timezone": xs:dayTimeDuration("-PT5H")
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime("1999-05-31T13:20:00-05:00")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">build-dateTime({ "hours": 13, "minutes": 30, "seconds": 4.2678 })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("13:30:04.2678")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
build-dateTime({ "year": 2007, "month": 5, "timezone": xs:dayTimeDuration("PT0S") })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:gYearMonth("2007-05Z")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-unix-dateTime"><head>fn:unix-dateTime</head><changes><change issue="959" PR="1358" date="2024-08-01">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a dateTime value for a Unix time.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="unix-dateTime" return-type="xs:dateTimeStamp" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:nonNegativeInteger?" default="0" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a dateTime value in UTC timezone for the Unix time specified
            by <code nobreak="false">$value</code> in milliseconds.
            The Unix time is defined in <bibref ref="ieee1003.1-2024"/>.</p><p>If the implementation supports data types from XSD 1.1 then the returned value will be
            an instance of <code nobreak="false">xs:dateTimeStamp</code>. Otherwise, the only guarantees are that it
            will be an instance of <code nobreak="false">xs:dateTime</code> and will have a timezone component.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">xs:dateTime('1970-01-01T00:00:00Z') + ($value otherwise 0) * seconds(0.001)</eg></def></gitem><gitem><label>Notes</label><def><note><p>By calling this convenience function, it can be ensured that the correct timezone
            is used for computing the Unix time.</p><p>Note that Unix time does not account for leap seconds. It assumes that every day has
            86,400 seconds.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">unix-dateTime()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('1970-01-01T00:00:00Z')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">unix-dateTime(1)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('1970-01-01T00:00:00.001Z')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">unix-dateTime(86400000)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('1970-01-02T00:00:00Z')</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Calculate the Unix time associated with a <code nobreak="false">xs:dateTime</code> value:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $value := current-dateTime()
return ($value - unix-dateTime()) div seconds(0.001)</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="comp.datetime"><head>Comparing date and time values</head><p>Date and time values can be compared using the function <function>fn:compare</function>.</p><p>
               <bibref ref="xmlschema-2"/>  states that the
                    order relation on date and time datatypes is
                    not a total order but a partial order because these
datatypes may or may not have a timezone.  This is handled as follows.
If either operand to a comparison function on date or time values does not have
                    an (explicit) timezone then, for the purpose of the operation, an implicit
                    timezone, provided by the dynamic context <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>, is assumed to be present as part of
                    the value. This creates a total order for all date and time values.</p><p>An <code nobreak="false">xs:dateTime</code> can be considered to consist of seven components:
<code nobreak="false">year</code>, <code nobreak="false">month</code>, <code nobreak="false">day</code>, <code nobreak="false">hour</code>, <code nobreak="false">minute</code>, 
<code nobreak="false">second</code> and <code nobreak="false">timezone</code>.  For <code nobreak="false">xs:dateTime</code> six components (<code nobreak="false">year</code>, 
<code nobreak="false">month</code>, <code nobreak="false">day</code>, <code nobreak="false">hour</code>, <code nobreak="false">minute</code> and <code nobreak="false">second</code>) are required  
and  <code nobreak="false">timezone</code> is optional.   For other date/time values, of the first six components, some are required 
			   and others must be <xtermref ref="dt-absent" spec="DM31">absent</xtermref>.  
			   <code nobreak="false">Timezone</code> is always optional.  For example, for <code nobreak="false">xs:date</code>, 
the <code nobreak="false">year</code>, <code nobreak="false">month</code> and <code nobreak="false">day</code> components are required and <code nobreak="false">hour</code>, 
<code nobreak="false">minute</code> and <code nobreak="false">second</code> components must be absent;  for <code nobreak="false">xs:time</code> the <code nobreak="false">hour</code>, 
<code nobreak="false">minute</code> and <code nobreak="false">second</code> components are required and <code nobreak="false">year</code>, <code nobreak="false">month</code> and 
<code nobreak="false">day</code> are missing;  for <code nobreak="false">xs:gDay</code>, <code nobreak="false">day</code> is required and <code nobreak="false">year</code>, 
<code nobreak="false">month</code>, <code nobreak="false">hour</code>, <code nobreak="false">minute</code> and <code nobreak="false">second</code> are missing.</p><note><p>In <bibref ref="xmlschema11-2"/>, a new <code nobreak="false">explicitTimezone</code> facet is available with values
            <code nobreak="false">optional</code>, <code nobreak="false">required</code>, or <code nobreak="false">prohibited</code> to 
            enable the timezone to be defined as mandatory or disallowed.</p></note><p>Values of the date/time datatypes <code nobreak="false">xs:time</code>, <code nobreak="false">xs:gMonthDay</code>, <code nobreak="false">xs:gMonth</code>, 
			and <code nobreak="false">xs:gDay</code>, can be considered to represent a sequence of recurring time instants or time periods.  
			An <code nobreak="false">xs:time</code> occurs every day.  An <code nobreak="false">xs:gMonth</code> occurs every year.  Comparison operators 
			on these datatypes compare the starting instants of equivalent occurrences in the recurring series.  
			These <code nobreak="false">xs:dateTime</code> values are calculated  as described below.</p><p>Comparison operators on <code nobreak="false">xs:date</code>, <code nobreak="false">xs:gYearMonth</code> and <code nobreak="false">xs:gYear</code> compare 
			their starting instants. These <code nobreak="false">xs:dateTime</code> values are calculated  as described below.</p><p>The starting instant of an occurrence of a date/time value is an <code nobreak="false">xs:dateTime</code> 
             calculated by filling 
			in the missing components of the local value from a reference <code nobreak="false">xs:dateTime</code>.  An example of a suitable
         reference <code nobreak="false">xs:dateTime</code> is <code nobreak="false">1972-01-01T00:00:00</code>. Then, for example, the starting
             instant corresponding to the <code nobreak="false">xs:date</code> value <code nobreak="false">2009-03-12</code> is 
             <code nobreak="false">2009-03-12T00:00:00</code>; the starting instant corresponding to the <code nobreak="false">xs:time</code> value
             <code nobreak="false">13:30:02</code> is <code nobreak="false">1972-01-01T13:30:02</code>; and the starting instant corresponding to the
             <code nobreak="false">gMonthDay</code> value <code nobreak="false">--02-29</code> is <code nobreak="false">1972-02-29T00:00:00</code> (which explains
             why a leap year was chosen for the reference).</p><note><p>In the previous version of this specification, the reference date/time chosen was
         <code nobreak="false">1972-12-31T00:00:00</code>. While this gives the same results, it produces a "starting instant" for 
         a <code nobreak="false">gMonth</code> or <code nobreak="false">gMonthDay</code> that bears no
         relation to the ordinary meaning of the term, and it also required special handling of short months. 
         The original choice was made to allow for leap seconds; but since leap seconds are not recognized 
         in date/time arithmetic, this is not actually necessary.</p></note><p>If the <code nobreak="false">xs:time</code> value written as
			<code nobreak="false">24:00:00</code> is to be compared, filling in the missing components gives <code nobreak="false">1972-01-01T00:00:00</code>, 
			because <code nobreak="false">24:00:00</code> is an alternative representation of <code nobreak="false">00:00:00</code> (the lexical value 
			<code nobreak="false">"24:00:00"</code> is
			converted to the time components { 0, 0, 0 } before the missing components are filled
			in). This has the consequence that when ordering <code nobreak="false">xs:time</code> values, 
			<code nobreak="false">24:00:00</code> is
			considered to be earlier than <code nobreak="false">23:59:59</code>. However, when ordering 
			<code nobreak="false">xs:dateTime</code>
			values, a time component of <code nobreak="false">24:00:00</code> is considered equivalent to <code nobreak="false">00:00:00</code> on the
			following day.</p><p>Note that the reference <code nobreak="false">xs:dateTime</code> does not have a timezone.  The <code nobreak="false">timezone</code> component 
			is never filled in from the reference <code nobreak="false">xs:dateTime</code>.  In some cases, if the date/time value does not 
			have a timezone, the implicit timezone from the dynamic context is used as the timezone.</p><note><p>This specification uses the reference <code nobreak="false">xs:dateTime 1972-01-01T00:00:00</code> in the description of the 
			   comparison operators.  Implementations may use other reference <code nobreak="false">xs:dateTime</code> values 
			   as long as they yield the same results.  The reference <code nobreak="false">xs:dateTime</code> used must meet the following 
			   constraints:  when it is used to supply components into <code nobreak="false">xs:gMonthDay</code> values, the year must allow 
			   for February 29 and so must be a leap year; when it is used to supply missing components into <code nobreak="false">xs:gDay</code> 
			   values, the month must allow for 31 days.  Different reference <code nobreak="false">xs:dateTime</code> values may be used for 
			   different operators.</p></note></div2><div2 id="component-extraction-dateTime"><head>Extracting components of dates and times</head><p>The date and time datatypes may be considered to be composite datatypes
                    in that they contain distinct properties or components. The extraction functions specified
                    below extract a single component from a date or time value. In all cases 
					the local value (that is, the original value as written, 
					without any timezone adjustment) is used. </p><note><p>A time written as <code nobreak="false">24:00:00</code> is treated as <code nobreak="false">00:00:00</code> on the
			following day.</p></note><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:year-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the year component of a <termref def="dt-gregorian"/> value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:month-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the month component of a <termref def="dt-gregorian"/> value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:day-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the day component of a <termref def="dt-gregorian"/> value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:hours-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the hours component of a <termref def="dt-gregorian"/> value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:minutes-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the minute component of a <termref def="dt-gregorian"/> value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:seconds-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the seconds component of a <termref def="dt-gregorian"/> value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:timezone-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the timezone component of a <termref def="dt-gregorian"/> value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:year-from-date</code></td><td rowspan="1" colspan="1">Returns the year component of an <code nobreak="false">xs:date</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:month-from-date</code></td><td rowspan="1" colspan="1">Returns the month component of an <code nobreak="false">xs:date</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:day-from-date</code></td><td rowspan="1" colspan="1">Returns the day component of an <code nobreak="false">xs:date</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:timezone-from-date</code></td><td rowspan="1" colspan="1">Returns the timezone component of an <code nobreak="false">xs:date</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:hours-from-time</code></td><td rowspan="1" colspan="1">Returns the hours component of an <code nobreak="false">xs:time</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:minutes-from-time</code></td><td rowspan="1" colspan="1">Returns the minutes component of an <code nobreak="false">xs:time</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:seconds-from-time</code></td><td rowspan="1" colspan="1">Returns the seconds component of an <code nobreak="false">xs:time</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:timezone-from-time</code></td><td rowspan="1" colspan="1">Returns the timezone component of an <code nobreak="false">xs:time</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parts-of-dateTime</code></td><td rowspan="1" colspan="1">Returns all the components of a <termref def="dt-gregorian"/> value.</td></tr></tbody></table><div3 id="func-year-from-dateTime"><head>fn:year-from-dateTime</head><changes><change issue="1448" PR="1481" date="2024-10-08">The function has been extended to handle other Gregorian types such as <code nobreak="false">xs:gYearMonth</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the year component of a <termref def="dt-gregorian"/> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="year-from-dateTime" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, or if the <code nobreak="false">year</code> component is absent, 
            the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> representing the year
            component in <code nobreak="false">$value</code>. The result may be negative.</p></def></gitem><gitem><label>Notes</label><def><note><p>The value space for <code nobreak="false">xs:dateTime</code> allows year zero. XSD 1.0, however, does not
            allow year zero, so if a date earlier that 0001 CE was produced by validating
            an XML document using an XSD 1.0 processor, the results may be unpredictable.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-dateTime(
  xs:dateTime("1999-05-31T13:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1999</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-dateTime(
  xs:dateTime("1999-05-31T21:30:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1999</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-dateTime(
  xs:dateTime("1999-12-31T19:20:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1999</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-dateTime(
  xs:dateTime("1999-12-31T24:00:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2000</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-dateTime(
  xs:dateTime("-0002-06-06T00:00:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">-2</eg><p><emph>(The result is the same whether XSD 1.0 or 1.1 is in use, despite
                  the absence of a year 0 in the XSD 1.0 value space.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-dateTime(
  xs:gYearMonth("2007-05Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2007</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-dateTime(
  xs:time("12:30:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-month-from-dateTime"><head>fn:month-from-dateTime</head><changes><change issue="1448" PR="1481" date="2024-10-08">The function has been extended to handle other Gregorian types such as <code nobreak="false">xs:gYearMonth</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the month component of a <termref def="dt-gregorian"/> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="month-from-dateTime" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, or if it contains no <code nobreak="false">month</code> component,
            the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> between <code nobreak="false">1</code> and
            <code nobreak="false">12</code>, both inclusive, representing the month component in 
             <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">month-from-dateTime(
  xs:dateTime("1999-05-31T13:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">5</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">month-from-dateTime(
  xs:dateTime("1999-12-31T19:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">12</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">month-from-dateTime(
  adjust-dateTime-to-timezone(
    xs:dateTime("1999-12-31T19:20:00-05:00"),
    xs:dayTimeDuration("PT0S")
  )
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">month-from-dateTime(
  xs:gYearMonth("2007-05Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">5</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">month-from-dateTime(
  xs:time("12:30:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-day-from-dateTime"><head>fn:day-from-dateTime</head><changes><change issue="1448" PR="1481" date="2024-10-08">The function has been extended to handle other Gregorian types such as <code nobreak="false">xs:gMonthDay</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the day component of a <termref def="dt-gregorian"/> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="day-from-dateTime" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, or if it contains no <code nobreak="false">day</code> component,
            the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> between <code nobreak="false">1</code> and
            <code nobreak="false">31</code>, both inclusive, representing the day component in the
            local value of <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">day-from-dateTime(
  xs:dateTime("1999-05-31T13:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">31</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">day-from-dateTime(
  xs:dateTime("1999-12-31T20:00:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">31</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">day-from-dateTime(
  adjust-dateTime-to-timezone(
    xs:dateTime("1999-12-31T19:20:00-05:00"),
    xs:dayTimeDuration("PT0S")
  )
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">day-from-dateTime(
  xs:gMonthDay("--05-31Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">31</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">day-from-dateTime(
  xs:time("12:30:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-hours-from-dateTime"><head>fn:hours-from-dateTime</head><changes><change issue="1448" PR="1481" date="2024-10-08">The function has been extended to handle other types including <code nobreak="false">xs:time</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the hours component of a <termref def="dt-gregorian"/> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="hours-from-dateTime" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, or if it contains no <code nobreak="false">hours</code>
            component, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> between <code nobreak="false">0</code> and
            <code nobreak="false">23</code>, both inclusive, representing the hours component in <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-dateTime(
  xs:dateTime("1999-05-31T08:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">8</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-dateTime(
  xs:dateTime("1999-12-31T21:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">21</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-dateTime(
  adjust-dateTime-to-timezone(
    xs:dateTime("1999-12-31T21:20:00-05:00"),
    xs:dayTimeDuration("PT0S")
  )
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-dateTime(
  xs:dateTime("1999-12-31T12:00:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">12</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-dateTime(
  xs:dateTime("1999-12-31T24:00:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">0</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-dateTime(
  xs:gYearMonth("2007-05Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-dateTime(
  xs:time("12:30:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">12</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-minutes-from-dateTime"><head>fn:minutes-from-dateTime</head><changes><change issue="1448" PR="1481" date="2024-10-08">The function has been extended to handle other types including <code nobreak="false">xs:time</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the minute component of a <termref def="dt-gregorian"/> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="minutes-from-dateTime" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, or if it contains no <code nobreak="false">minutes</code>
            component, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> value between <code nobreak="false">0</code>
            and <code nobreak="false">59</code>, both inclusive, representing the minute component in the local value of
            <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">minutes-from-dateTime(
  xs:dateTime("1999-05-31T13:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">20</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">minutes-from-dateTime(
  xs:dateTime("1999-05-31T13:30:00+05:30")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">30</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">minutes-from-dateTime(
  xs:gYearMonth("2007-05Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">minutes-from-dateTime(
  xs:time("12:30:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">30</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-seconds-from-dateTime"><head>fn:seconds-from-dateTime</head><glist><gitem><label>Summary</label><def><p>Returns the seconds component of a <termref def="dt-gregorian"/> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="seconds-from-dateTime" return-type="xs:decimal?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, or if it contains no <code nobreak="false">seconds</code>
            component, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:decimal</code> value greater than or equal
            to zero and less than 60, representing the seconds and fractional seconds in <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds-from-dateTime(
  xs:dateTime("1999-05-31T13:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">0</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds-from-dateTime(
  xs:gYearMonth("2007-05Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">seconds-from-dateTime(
  xs:time("12:30:14.5")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">14.5</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-timezone-from-dateTime"><head>fn:timezone-from-dateTime</head><changes><change issue="1448" PR="1481" date="2024-10-08">The function has been extended to handle other types such as <code nobreak="false">xs:gYearMonth</code>.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the timezone component of a <termref def="dt-gregorian"/> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="timezone-from-dateTime" return-type="xs:dayTimeDuration?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns the timezone component of <code nobreak="false">$value</code>, if any. If
            <code nobreak="false">$value</code> has a timezone component, then the result is an
               <code nobreak="false">xs:dayTimeDuration</code> that indicates deviation from UTC; its value may
            range from +14:00 to -14:00 hours, both inclusive. If <code nobreak="false">$value</code> has no timezone
            component, the result is the empty sequence.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">timezone-from-dateTime(
  xs:dateTime("1999-05-31T13:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("-PT5H")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">timezone-from-dateTime(
  xs:dateTime("2000-06-12T13:20:00Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("PT0S")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">timezone-from-dateTime(
  xs:dateTime("2004-08-27T00:00:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">timezone-from-dateTime(
  xs:gYearMonth("2007-05Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("PT0S")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">timezone-from-dateTime(
  xs:time("12:30:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-year-from-date"><head>fn:year-from-date</head><glist><gitem><label>Summary</label><def><p>Returns the year component of an <code nobreak="false">xs:date</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="year-from-date" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> representing the year in the
            local value of <code nobreak="false">$value</code>. The value may be negative. </p></def></gitem><gitem><label>Notes</label><def><note><p>The value space for <code nobreak="false">xs:date</code> allows year zero. XSD 1.0, however, does not
            allow year zero, so if a date earlier that 0001 CE was produced by validating
            an XML document using an XSD 1.0 processor, the results may be unpredictable.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-date(
  xs:date("1999-05-31")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1999</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-date(
  xs:date("2000-01-01+05:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2000</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">year-from-date(
  xs:date("-0002-06-01")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">-2</eg><p><emph>(The result is the same whether XSD 1.0 or 1.1 is in use, despite
               the absence of a year 0 in the XSD 1.0 value space.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-month-from-date"><head>fn:month-from-date</head><glist><gitem><label>Summary</label><def><p>Returns the month component of an <code nobreak="false">xs:date</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="month-from-date" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> between
            <code nobreak="false">1</code> and <code nobreak="false">12</code>, both
            inclusive, representing the month component in the local value of <code nobreak="false">$value</code>.
         </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">month-from-date(
  xs:date("1999-05-31-05:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">5</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">month-from-date(
  xs:date("2000-01-01+05:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-day-from-date"><head>fn:day-from-date</head><glist><gitem><label>Summary</label><def><p>Returns the day component of an <code nobreak="false">xs:date</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="day-from-date" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> between
            <code nobreak="false">1</code> and <code nobreak="false">31</code>, both
            inclusive, representing the day component in the localized value of
            <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">day-from-date(
  xs:date("1999-05-31-05:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">31</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">day-from-date(
  xs:date("2000-01-01+05:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-timezone-from-date"><head>fn:timezone-from-date</head><glist><gitem><label>Summary</label><def><p>Returns the timezone component of an <code nobreak="false">xs:date</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="timezone-from-date" return-type="xs:dayTimeDuration?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns the timezone component of <code nobreak="false">$value</code>, if any. If
            <code nobreak="false">$value</code> has a timezone component, then the result is an
               <code nobreak="false">xs:dayTimeDuration</code> that indicates deviation from UTC; its value may
            range from +14:00 to -14:00 hours, both inclusive. If <code nobreak="false">$value</code> has no timezone
            component, the result is the empty sequence.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">timezone-from-date(
  xs:date("1999-05-31-05:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("-PT5H")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">timezone-from-date(
  xs:date("2000-06-12Z")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("PT0S")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-hours-from-time"><head>fn:hours-from-time</head><glist><gitem><label>Summary</label><def><p>Returns the hours component of an <code nobreak="false">xs:time</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="hours-from-time" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> between
            <code nobreak="false">0</code> and <code nobreak="false">23</code>, both
            inclusive, representing the value of the hours component in the local value of
            <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>Assume that the dynamic context provides an implicit timezone value of
                  <code nobreak="false">-05:00</code>. </p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">hours-from-time(xs:time("11:23:00"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">11</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">hours-from-time(xs:time("21:23:00"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">21</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">hours-from-time(xs:time("01:23:00+05:00"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">hours-from-time(
  adjust-time-to-timezone(
    xs:time("01:23:00+05:00"),
    xs:dayTimeDuration("PT0S")
  )
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">20</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">hours-from-time(xs:time("24:00:00"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-minutes-from-time"><head>fn:minutes-from-time</head><glist><gitem><label>Summary</label><def><p>Returns the minutes component of an <code nobreak="false">xs:time</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="minutes-from-time" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:integer</code> value between <code nobreak="false">0</code>
            and <code nobreak="false">59</code>, both inclusive, representing the value of the minutes component
            in the local value of <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">minutes-from-time(xs:time("13:00:00Z"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-seconds-from-time"><head>fn:seconds-from-time</head><glist><gitem><label>Summary</label><def><p>Returns the seconds component of an <code nobreak="false">xs:time</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="seconds-from-time" return-type="xs:decimal?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:decimal</code> value greater than or equal
            to zero and less than 60, representing the seconds and fractional seconds in the local
            value of <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">seconds-from-time(xs:time("13:20:10.5"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">10.5</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-timezone-from-time"><head>fn:timezone-from-time</head><glist><gitem><label>Summary</label><def><p>Returns the timezone component of an <code nobreak="false">xs:time</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="timezone-from-time" return-type="xs:dayTimeDuration?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns the timezone component of <code nobreak="false">$value</code>, if any. If
            <code nobreak="false">$value</code> has a timezone component, then the result is an
               <code nobreak="false">xs:dayTimeDuration</code> that indicates deviation from UTC; its value may
            range from +14:00 to -14:00 hours, both inclusive. If <code nobreak="false">$value</code> has no timezone
            component, the result is the empty sequence.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">timezone-from-time(xs:time("13:20:00-05:00"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:dayTimeDuration("-PT5H")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">timezone-from-time(xs:time("13:20:00"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-parts-of-dateTime"><head>fn:parts-of-dateTime</head><changes><change>New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns all the components of a <termref def="dt-gregorian"/> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parts-of-dateTime" return-type-ref="dateTime-record" return-type-ref-occurs="?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:dateTime | xs:date | xs:time | xs:gYear | xs:gYearMonth | xs:gMonth | xs:gMonthDay | xs:gDay)?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns a record whose fields are as follows. All entries will be present,
         even when the value is an empty sequence.</p><table><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><code nobreak="false">year</code></td><td rowspan="1" colspan="1">Generally, the value of <code nobreak="false">fn:year-from-dateTime($value)</code>: but
                  see the notes below regarding negative years.</td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">month</code></td><td rowspan="1" colspan="1">The value of <code nobreak="false">fn:month-from-dateTime($value)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">day</code></td><td rowspan="1" colspan="1">The value of <code nobreak="false">fn:day-from-dateTime($value)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">hours</code></td><td rowspan="1" colspan="1">The value of <code nobreak="false">fn:hours-from-dateTime($value)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">minutes</code></td><td rowspan="1" colspan="1">The value of <code nobreak="false">fn:minutes-from-dateTime($value)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">seconds</code></td><td rowspan="1" colspan="1">The value of <code nobreak="false">fn:seconds-from-dateTime($value)</code></td></tr><tr><td rowspan="1" colspan="1"><code nobreak="false">timezone</code></td><td rowspan="1" colspan="1">The value of <code nobreak="false">fn:timezone-from-dateTime($value)</code></td></tr></tbody></table><p>The range of years supported is <termref def="implementation-defined"/>. If years earlier than
         0001 CE are supported, however, the year number returned by this function 
         follows the proleptic Gregorian calendar as defined
         in ISO 8601. This means that the year before 0001 CE is numbered zero, and the year before that
         is numbered -1.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parts-of-dateTime(
  xs:dateTime("1999-05-31T13:20:00-05:00")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "year": 1999, "month": 5, "day": 31, 
  "hours": 13, "minutes": 20, "seconds": 0, 
  "timezone": xs:dayTimeDuration("-PT5H") }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parts-of-dateTime(
  xs:time("13:30:04.2678")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "year": (), "month": (), "day": (), 
  "hours": 13, "minutes": 30, "seconds": 4.2678, 
  "timezone": () }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parts-of-dateTime(
  xs:gYearMonth("2007-05Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "year": 2007, "month": 5, "day": (), 
  "hours": (), "minutes": (), "seconds": (), 
  "timezone": xs:dayTimeDuration("PT0S") }</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="timezone.functions"><head>Adjusting timezones on dates and times</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:adjust-dateTime-to-timezone</code></td><td rowspan="1" colspan="1">Adjusts an <code nobreak="false">xs:dateTime</code> value to a specific timezone, or to no timezone at
            all.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:adjust-date-to-timezone</code></td><td rowspan="1" colspan="1">Adjusts an <code nobreak="false">xs:date</code> value to a specific timezone, or to no timezone at all;
            the result is the date in the target timezone that contains the starting instant of the
            supplied date.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:adjust-time-to-timezone</code></td><td rowspan="1" colspan="1">Adjusts an <code nobreak="false">xs:time</code> value to a specific timezone, or to no timezone at
            all.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:civil-timezone</code></td><td rowspan="1" colspan="1">Returns the timezone offset from UTC that is in conventional use at a given place and time.</td></tr></tbody></table><p>These functions adjust the timezone component of an <code nobreak="false">xs:dateTime</code>, <code nobreak="false">xs:date</code> or
                    <code nobreak="false">xs:time</code> value.  The <code nobreak="false">$timezone</code> argument to these functions is defined as an 
					<code nobreak="false">xs:dayTimeDuration</code> but must be a valid timezone value.</p><div3 id="func-adjust-dateTime-to-timezone"><head>fn:adjust-dateTime-to-timezone</head><glist><gitem><label>Summary</label><def><p>Adjusts an <code nobreak="false">xs:dateTime</code> value to a specific timezone, or to no timezone at
            all.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="adjust-dateTime-to-timezone" return-type="xs:dateTime?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:dateTime?"/><arg name="timezone" type="xs:dayTimeDuration?" default="fn:implicit-timezone()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p> If <code nobreak="false">$value</code> is the empty sequence, then the function returns the empty
            sequence.</p><p> If <code nobreak="false">$value</code> does not have a timezone component and <code nobreak="false">$timezone</code> is
            the empty sequence, then the result is <code nobreak="false">$value</code>.</p><p> If <code nobreak="false">$value</code> does not have a timezone component and <code nobreak="false">$timezone</code> is
            not the empty sequence, then the result is <code nobreak="false">$value</code> with <code nobreak="false">$timezone</code>
            as the timezone component.</p><p> If <code nobreak="false">$value</code> has a timezone component and <code nobreak="false">$timezone</code> is the empty
            sequence, then the result is the local value of <code nobreak="false">$value</code> without its timezone
            component.</p><p> If <code nobreak="false">$value</code> has a timezone component and <code nobreak="false">$timezone</code> is not the
            empty sequence, then the result is the <code nobreak="false">xs:dateTime</code> value that is equal to
            <code nobreak="false">$value</code> and that has a timezone component equal to
            <code nobreak="false">$timezone</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p> A dynamic error is raised <errorref class="DT" code="0003"/> if <code nobreak="false">$timezone</code>
            is less than <code nobreak="false">-PT14H</code> or greater than <code nobreak="false">PT14H</code> or is not an
            integral number of minutes.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $tz-10 := xs:dayTimeDuration("-PT10H")</eg></td></tr></tbody></table><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p> Assume the dynamic context provides an implicit timezone of <code nobreak="false">-05:00
                  (-PT5H0M)</code>.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  xs:dateTime('2002-03-07T10:00:00')
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2002-03-07T10:00:00-05:00')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  xs:dateTime('2002-03-07T10:00:00-07:00')
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2002-03-07T12:00:00-05:00')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  xs:dateTime('2002-03-07T10:00:00'),
  $tz-10
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2002-03-07T10:00:00-10:00')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  xs:dateTime('2002-03-07T10:00:00-07:00'),
  $tz-10
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2002-03-07T07:00:00-10:00')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  xs:dateTime('2002-03-07T10:00:00-07:00'),
  xs:dayTimeDuration("PT10H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2002-03-08T03:00:00+10:00')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  xs:dateTime('2002-03-07T00:00:00+01:00'),
  xs:dayTimeDuration("-PT8H")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2002-03-06T15:00:00-08:00')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  xs:dateTime('2002-03-07T10:00:00'),
  ()
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2002-03-07T10:00:00')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  xs:dateTime('2002-03-07T10:00:00-07:00'),
  ()
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime('2002-03-07T10:00:00')</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-adjust-date-to-timezone"><head>fn:adjust-date-to-timezone</head><glist><gitem><label>Summary</label><def><p>Adjusts an <code nobreak="false">xs:date</code> value to a specific timezone, or to no timezone at all;
            the result is the date in the target timezone that contains the starting instant of the
            supplied date.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="adjust-date-to-timezone" return-type="xs:date?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/><arg name="timezone" type="xs:dayTimeDuration?" default="fn:implicit-timezone()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p> If <code nobreak="false">$value</code> is the empty sequence, then the function returns the empty
            sequence.</p><p> If <code nobreak="false">$value</code> does not have a timezone component and <code nobreak="false">$timezone</code> is
            the empty sequence, then the result is <code nobreak="false">$value</code>.</p><p> If <code nobreak="false">$value</code> does not have a timezone component and <code nobreak="false">$timezone</code> is
            not the empty sequence, then the result is <code nobreak="false">$value</code> with <code nobreak="false">$timezone</code>
            as the timezone component.</p><p> If <code nobreak="false">$value</code> has a timezone component and <code nobreak="false">$timezone</code> is the empty
            sequence, then the result is the local value of <code nobreak="false">$value</code> without its timezone
            component.</p><p> If <code nobreak="false">$value</code> has a timezone component and <code nobreak="false">$timezone</code> is not the
            empty sequence, then:</p><ulist><item><p>Let <code nobreak="false">$dt</code> be the value of <code nobreak="false">fn:dateTime($arg,
                     xs:time('00:00:00'))</code>.</p></item><item><p>Let <code nobreak="false">$adt</code> be the value of <code nobreak="false">fn:adjust-dateTime-to-timezone($dt,
                     $timezone)</code></p></item><item><p>The function returns the value of <code nobreak="false">xs:date($adt)</code></p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DT" code="0003"/> if <code nobreak="false">$timezone</code>
            is less than <code nobreak="false">-PT14H</code> or greater than <code nobreak="false">PT14H</code> or is not an
            integral number of minutes.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $tz-10 := xs:dayTimeDuration("-PT10H")</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>Assume the dynamic context provides an implicit timezone of <code nobreak="false">-05:00
                  (-PT5H0M)</code>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-date-to-timezone(
  xs:date("2002-03-07")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2002-03-07-05:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-date-to-timezone(
  xs:date("2002-03-07-07:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2002-03-07-05:00")</eg><p><emph>(<code nobreak="false">$value</code> is converted to
                     <code nobreak="false">xs:dateTime("2002-03-07T00:00:00-07:00")</code>. This is adjusted to the
                  implicit timezone, giving <code nobreak="false">"2002-03-07T02:00:00-05:00"</code>.
               ).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-date-to-timezone(
  xs:date("2002-03-07"),
  $tz-10
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2002-03-07-10:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-date-to-timezone(
  xs:date("2002-03-07-07:00"),
  $tz-10
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2002-03-06-10:00")</eg><p><emph>(<code nobreak="false">$value</code> is converted to
                  <code nobreak="false">xs:dateTime("2002-03-07T00:00:00-07:00")</code>.
                  This is adjusted to the given timezone,
                  giving <code nobreak="false">"2002-03-06T21:00:00-10:00"</code>. ).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-date-to-timezone(
  xs:date("2002-03-07"),
  ()
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2002-03-07")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-date-to-timezone(
  xs:date("2002-03-07-07:00"),
  ()
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2002-03-07")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-adjust-time-to-timezone"><head>fn:adjust-time-to-timezone</head><glist><gitem><label>Summary</label><def><p>Adjusts an <code nobreak="false">xs:time</code> value to a specific timezone, or to no timezone at
            all.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="adjust-time-to-timezone" return-type="xs:time?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/><arg name="timezone" type="xs:dayTimeDuration?" default="fn:implicit-timezone()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p> If <code nobreak="false">$value</code> is the empty sequence, then the function returns the empty
            sequence.</p><p> If <code nobreak="false">$value</code> does not have a timezone component and <code nobreak="false">$timezone</code> is
            the empty sequence, then the result is <code nobreak="false">$value</code>.</p><p> If <code nobreak="false">$value</code> does not have a timezone component and <code nobreak="false">$timezone</code> is
            not the empty sequence, then the result is <code nobreak="false">$value</code> with <code nobreak="false">$timezone</code>
            as the timezone component.</p><p> If <code nobreak="false">$value</code> has a timezone component and <code nobreak="false">$timezone</code> is the empty
            sequence, then the result is the localized value of <code nobreak="false">$value</code> without its
            timezone component.</p><p> If <code nobreak="false">$value</code> has a timezone component and <code nobreak="false">$timezone</code> is not the
            empty sequence, then:</p><ulist><item><p>Let <code nobreak="false">$dt</code> be the <code nobreak="false">xs:dateTime</code> value
                  <code nobreak="false">fn:dateTime(xs:date('1972-12-31'), $value)</code>.</p></item><item><p>Let <code nobreak="false">$adt</code> be the value of <code nobreak="false">fn:adjust-dateTime-to-timezone($dt,
                     $timezone)</code>
               </p></item><item><p>The function returns the <code nobreak="false">xs:time</code> value
                  <code nobreak="false">xs:time($adt)</code>.</p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DT" code="0003"/> if <code nobreak="false">$timezone</code>
            is less than <code nobreak="false">-PT14H</code> or greater than <code nobreak="false">PT14H</code> or if does not
            contain an integral number of minutes.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $tz-10 := xs:dayTimeDuration("-PT10H")</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>Assume the dynamic context provides an implicit timezone of <code nobreak="false">-05:00
                  (-PT5H0M)</code>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-time-to-timezone(
  xs:time("10:00:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("10:00:00-05:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-time-to-timezone(
  xs:time("10:00:00-07:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("12:00:00-05:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-time-to-timezone(
  xs:time("10:00:00"),
  $tz-10
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("10:00:00-10:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-time-to-timezone(
  xs:time("10:00:00-07:00"),
  $tz-10
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("07:00:00-10:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-time-to-timezone(
  xs:time("10:00:00"),
  ()
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("10:00:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-time-to-timezone(
  xs:time("10:00:00-07:00"),
  ()
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("10:00:00")</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-time-to-timezone(
  xs:time("10:00:00-07:00"),
  xs:dayTimeDuration("PT10H")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("03:00:00+10:00")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-civil-timezone"><head>fn:civil-timezone</head><changes><change issue="1539" PR="1545" date="2024-11-05">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the timezone offset from UTC that is in conventional use at a given place and time.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="civil-timezone" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:dateTime"/><arg name="place" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		default place.
	</p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>This function uses a database of civil timezones (including daylight savings time) to return
         the timezone offset for a given date/time and place. For example, the timezone offset for New York
         on 31 December 2024 would be <code nobreak="false">-PT5H</code>.</p><p>If the <code nobreak="false">$place</code> argument is empty then the
         <xtermref spec="XP40" ref="dt-default-place"/> from the dynamic context is used.</p><p>If the supplied <code nobreak="false">$value</code> has no timezone then the implicit timezone from the dynamic
         context is used. This is unrelated to the timezone applicable to the requested <code nobreak="false">$place</code>.</p><p>The intended use of the <code nobreak="false">$place</code> argument is to identify
 the place where an event
represented by the <code nobreak="false">$value</code> argument took place or will take place.
                  The value must be an IANA timezone name as defined in the IANA timezone database <bibref ref="olson"/>.
   Examples are <code nobreak="false">"America/New_York"</code> and <code nobreak="false">"Europe/Rome"</code>.</p><p>The result of the function is the civil timezone offset applicable to the given date/time
   and place, as determined by the IANA timezone database or an alternative authoritative source.</p></def></gitem><gitem><label>Error Conditions</label><def><p> A dynamic error is raised <errorref class="DT" code="0004"/> if no timezone information is available for the given date/time and place.
         This includes the case where the given place is not present in the timezone database,
         and also the case where the information available for that place does not cover a sufficient range
         of dates.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">civil-timezone(
  xs:dateTime('2024-12-31T23:59:59'), 'America/New_York')
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('-PT5H')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">civil-timezone(
  xs:dateTime('2024-06-30T23:59:59'), 'America/New_York')
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration('-PT4H')</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">adjust-dateTime-to-timezone(
  current-dateTime(),
  civil-timezone(current-dateTime(), 'America/New_York')
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The current civil date and time in New York.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">civil-timezone(xs:dateTime('2024-07-01T09:00:00'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>If the default place is a location in the same timezone 
                  as (say) Paris, then <code nobreak="false">PT2H</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="dateTime-arithmetic"><head>Arithmetic operators on durations, dates, and times</head><p>These functions support adding or subtracting a duration value to or from an
                    <code nobreak="false">xs:dateTime</code>, an <code nobreak="false">xs:date</code> or an <code nobreak="false">xs:time</code>
                    value. Appendix E of <bibref ref="xmlschema-2"/> describes an algorithm for
                    performing such operations.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-dateTimes</code></td><td rowspan="1" colspan="1">Returns an <code nobreak="false">xs:dayTimeDuration</code> representing the amount of elapsed time
            between the instants <code nobreak="false">arg2</code> and <code nobreak="false">arg1</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-dates</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:dayTimeDuration</code> that corresponds to the elapsed time between
            the starting instant of <code nobreak="false">$arg2</code> and the starting instant of
               <code nobreak="false">$arg2</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-times</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:dayTimeDuration</code> that corresponds to the elapsed time between
            the values of <code nobreak="false">$arg2</code> and <code nobreak="false">$arg1</code> treated as times on the same
            date.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:add-yearMonthDuration-to-dateTime</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:dateTime</code> that is a given duration after a specified
               <code nobreak="false">xs:dateTime</code> (or before, if the duration is negative).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:add-dayTimeDuration-to-dateTime</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:dateTime</code> that is a given duration after a specified
               <code nobreak="false">xs:dateTime</code> (or before, if the duration is negative).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-yearMonthDuration-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:dateTime</code> that is a given duration before a specified
               <code nobreak="false">xs:dateTime</code> (or after, if the duration is negative).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-dayTimeDuration-from-dateTime</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:dateTime</code> that is a given duration before a specified
               <code nobreak="false">xs:dateTime</code> (or after, if the duration is negative).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:add-yearMonthDuration-to-date</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:date</code> that is a given duration after a specified
               <code nobreak="false">xs:date</code> (or before, if the duration is negative).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:add-dayTimeDuration-to-date</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:date</code> that is a given duration after a specified
               <code nobreak="false">xs:date</code> (or before, if the duration is negative).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-yearMonthDuration-from-date</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:date</code> that is a given duration before a specified
               <code nobreak="false">xs:date</code> (or after, if the duration is negative).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-dayTimeDuration-from-date</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:date</code> that is a given duration before a specified
               <code nobreak="false">xs:date</code> (or after, if the duration is negative).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:add-dayTimeDuration-to-time</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:time</code> value that is a given duration after a specified
               <code nobreak="false">xs:time</code> (or before, if the duration is negative or causes wrap-around
            past midnight)</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">op:subtract-dayTimeDuration-from-time</code></td><td rowspan="1" colspan="1">Returns the <code nobreak="false">xs:time</code> value that is a given duration before a specified
               <code nobreak="false">xs:time</code> (or after, if the duration is negative or causes wrap-around
            past midnight)</td></tr></tbody></table><div3 id="duration-limits"><head>Limits and precision</head><p>A processor that limits the number of digits in date and time datatype
                  representations may encounter overflow and underflow conditions when it
                  tries to execute the functions in this section. In
                  these situations, the processor <rfc2119>must</rfc2119> return P0M or PT0S in
                  case of duration underflow and 00:00:00 in case of time underflow.
                  It <rfc2119>must</rfc2119> raise a dynamic error
                  <errorref class="DT" code="0001"/> in case of overflow.</p><p>The value spaces of the two totally ordered subtypes of
                  <code nobreak="false">xs:duration</code> described in <specref ref="duration-subtypes"/> are
                  <code nobreak="false">xs:integer</code> months for <code nobreak="false">xs:yearMonthDuration</code>
                  and <code nobreak="false">xs:decimal</code> seconds for <code nobreak="false">xs:dayTimeDuration</code>. If
                  a processor limits the number of digits allowed in the representation of
                  <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:decimal</code> then overflow and
                  underflow situations can arise when it tries to execute the functions in
                  <specref ref="duration-arithmetic"/>. In these situations the processor
                  <rfc2119>must</rfc2119> return zero in case of numeric underflow and P0M
                  or PT0S in case of duration underflow. It <rfc2119>must</rfc2119> raise a
                  dynamic error <errorref class="DT" code="0002"/> in case of overflow.</p></div3><div3 id="func-subtract-dateTimes"><head>op:subtract-dateTimes</head><glist><gitem><label>Summary</label><def><p>Returns an <code nobreak="false">xs:dayTimeDuration</code> representing the amount of elapsed time
            between the instants <code nobreak="false">arg2</code> and <code nobreak="false">arg1</code>.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">-</code>
         operator when applied to two <code nobreak="false">xs:dateTime</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-dateTimes" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dateTime"/><arg name="arg2" type="xs:dateTime"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>If either <code nobreak="false">$arg1</code> or <code nobreak="false">$arg2</code> do not contain an explicit timezone
            then, for the purpose of the operation, the implicit timezone provided by the dynamic
            context (See <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.) is
            assumed to be present as part of the value.</p><p>The function returns the elapsed time between the date/time instant <code nobreak="false">arg2</code>
            and the date/time instant <code nobreak="false">arg1</code>, computed according to the algorithm given
            in Appendix E of <bibref ref="xmlschema-2"/>, and expressed as a
               <code nobreak="false">xs:dayTimeDuration</code>.</p><p>If the normalized value of <code nobreak="false">$arg1</code> precedes in time the normalized value of
               <code nobreak="false">$arg2</code>, then the returned value is a negative duration.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>Assume that the dynamic context provides an implicit timezone value of
                  <code nobreak="false">-05:00</code>.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dateTimes(
  xs:dateTime("2000-10-30T06:12:00"),
  xs:dateTime("1999-11-28T09:00:00Z")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("P337DT2H12M")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-dates"><head>op:subtract-dates</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:dayTimeDuration</code> that corresponds to the elapsed time between
            the starting instant of <code nobreak="false">$arg2</code> and the starting instant of
               <code nobreak="false">$arg2</code>.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">-</code> operator
         when applied to two <code nobreak="false">xs:date</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-dates" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:date"/><arg name="arg2" type="xs:date"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>If either <code nobreak="false">$arg1</code> or <code nobreak="false">$arg2</code> do not contain an explicit timezone
            then, for the purpose of the operation, the implicit timezone provided by the dynamic
            context (See <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.) is
            assumed to be present as part of the value.</p><p>The starting instant of an <code nobreak="false">xs:date</code> is the <code nobreak="false">xs:dateTime</code> at
               <code nobreak="false">00:00:00</code> on that date. </p><p>The function returns the result of subtracting the two starting instants using
               <code nobreak="false">op:subtract-dateTimes</code>.</p><p>If the starting instant of <code nobreak="false">$arg1</code> precedes in time the starting instant of
               <code nobreak="false">$arg2</code>, then the returned value is a negative duration.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>Assume that the dynamic context provides an implicit timezone value of
               <code nobreak="false">Z</code>. </p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dates(
  xs:date("2000-10-30"),
  xs:date("1999-11-28")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("P337D")</eg><p><emph>(The normalized values of the two starting instants are <code nobreak="false">{ 2000,
                  10, 30, 0, 0, 0, xs:dayTimeDuration("PT0S") }</code> and <code nobreak="false">{ 1999, 11, 28, 0, 0, 0,
                     xs:dayTimeDuration("PT0S") }</code>.)</emph></p></td></tr><tr><td colspan="2" rowspan="1"><p>Now assume that the dynamic context provides an implicit timezone value of
                  <code nobreak="false">+05:00</code>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dates(
  xs:date("2000-10-30"),
  xs:date("1999-11-28Z")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("P336DT19H")</eg><p><emph>( The normalized values of the two starting instants are <code nobreak="false">{ 2000,
                  10, 29, 19, 0, 0, xs:dayTimeDuration("PT0S") }</code> and <code nobreak="false">{ 1999, 11, 28, 0, 0, 0,
                     xs:dayTimeDuration("PT0S") }</code>.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dates(
  xs:date("2000-10-15-05:00"),
  xs:date("2000-10-10+02:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("P5DT7H")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-times"><head>op:subtract-times</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:dayTimeDuration</code> that corresponds to the elapsed time between
            the values of <code nobreak="false">$arg2</code> and <code nobreak="false">$arg1</code> treated as times on the same
            date.</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of the <code nobreak="false">-</code> operator
         when applied to two <code nobreak="false">xs:time</code> values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-times" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:time"/><arg name="arg2" type="xs:time"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of the expression:</p><eg xml:space="preserve">op-subtract-dateTimes(
        dateTime(xs:date('1972-12-31'), $arg1),
        dateTime(xs:date('1972-12-31'), $arg2))</eg></def></gitem><gitem><label>Notes</label><def><note><p>Any other reference date would work equally well.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><p>Assume that the dynamic context provides an implicit timezone value of
                  <code nobreak="false">-05:00</code>. Assume, also, that the date components of the reference
                  <code nobreak="false">xs:dateTime</code> correspond to <code nobreak="false">"1972-12-31"</code>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-times(
  xs:time("11:12:00Z"),
  xs:time("04:00:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("PT2H12M")</eg><p><emph>(This is obtained by subtracting from the <code nobreak="false">xs:dateTime</code>
                  value <code nobreak="false">{ 1972, 12, 31, 11, 12, 0, xs:dayTimeDuration("PT0S") }</code> the <code nobreak="false">xs:dateTime</code>
                  value <code nobreak="false">{ 1972, 12, 31, 9, 0, 0, xs:dayTimeDuration("PT0S") }</code>.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-times(
  xs:time("11:00:00-05:00"),
  xs:time("21:30:00+05:30")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("PT0S")</eg><p><emph>(The two <code nobreak="false">xs:dateTime</code> values are <code nobreak="false">{ 1972, 12, 31, 11,
                  0, 0, xs:dayTimeDuration("-PT5H") }</code> and <code nobreak="false">{ 1972, 12, 31, 21, 30, 0, xs:dayTimeDuration("PT5H30M") }</code>. These
                  normalize to <code nobreak="false">{ 1972, 12, 31, 16, 0, 0, xs:dayTimeDuration("PT0S") }</code>
                  and <code nobreak="false">{ 1972, 12, 31, 16, 0, 0, xs:dayTimeDuration("PT0S") }</code>.
               ).</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-times(
  xs:time("17:00:00-06:00"),
  xs:time("08:00:00+09:00")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("P1D")</eg><p><emph>(The two normalized <code nobreak="false">xs:dateTime</code> values are <code nobreak="false">{ 1972,
                  12, 31, 23, 0, 0, xs:dayTimeDuration("PT0S") }</code> and <code nobreak="false">{ 1972, 12, 30, 23, 0, 0,
                     xs:dayTimeDuration("PT0S") }</code>.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-times(
  xs:time("24:00:00"),
  xs:time("23:59:59")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dayTimeDuration("-PT23H59M59S")</eg><p><emph>(The two normalized <code nobreak="false">xs:dateTime</code> values are <code nobreak="false">{ 1972,
                     12, 31, 0, 0, 0, () }</code> and <code nobreak="false">{ 1972, 12, 31, 23, 59, 59.0,
                  () }</code>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-add-yearMonthDuration-to-dateTime"><head>op:add-yearMonthDuration-to-dateTime</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:dateTime</code> that is a given duration after a specified
               <code nobreak="false">xs:dateTime</code> (or before, if the duration is negative).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the
         semantics of the <code nobreak="false">+</code> operator when applied to an <code nobreak="false">xs:dateTime</code> and an
            <code nobreak="false">xs:yearMonthDuration</code> value. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="add-yearMonthDuration-to-dateTime" return-type="xs:dateTime" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dateTime"/><arg name="arg2" type="xs:yearMonthDuration"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of adding <code nobreak="false">$arg2</code> to the value of
               <code nobreak="false">$arg1</code> using the algorithm described in Appendix E of <bibref ref="xmlschema-2"/>, disregarding the rule about leap seconds. If <code nobreak="false">$arg2</code>
            is negative, then the result <code nobreak="false">xs:dateTime</code> precedes <code nobreak="false">$arg1</code>.</p><p>The result has the same timezone as <code nobreak="false">$arg1</code>. If <code nobreak="false">$arg1</code> has no
            timezone, the result has no timezone. </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:add-yearMonthDuration-to-dateTime(
  xs:dateTime("2000-10-30T11:12:00"),
  xs:yearMonthDuration("P1Y2M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime("2001-12-30T11:12:00")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-add-dayTimeDuration-to-dateTime"><head>op:add-dayTimeDuration-to-dateTime</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:dateTime</code> that is a given duration after a specified
               <code nobreak="false">xs:dateTime</code> (or before, if the duration is negative).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics
         of the <code nobreak="false">+</code> operator when applied to an <code nobreak="false">xs:dateTime</code> and an
            <code nobreak="false">xs:dayTimeDuration</code> value. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="add-dayTimeDuration-to-dateTime" return-type="xs:dateTime" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dateTime"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of adding <code nobreak="false">$arg2</code> to the value of
               <code nobreak="false">$arg1</code> using the algorithm described in Appendix E of <bibref ref="xmlschema-2"/>, disregarding the rule about leap seconds. If <code nobreak="false">$arg2</code>
            is negative, then the result <code nobreak="false">xs:dateTime</code> precedes <code nobreak="false">$arg1</code>.</p><p>The result has the same timezone as <code nobreak="false">$arg1</code>. If <code nobreak="false">$arg1</code> has no
            timezone, the result has no timezone. </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:add-dayTimeDuration-to-dateTime(
  xs:dateTime("2000-10-30T11:12:00"),
  xs:dayTimeDuration("P3DT1H15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime("2000-11-02T12:27:00")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-yearMonthDuration-from-dateTime"><head>op:subtract-yearMonthDuration-from-dateTime</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:dateTime</code> that is a given duration before a specified
               <code nobreak="false">xs:dateTime</code> (or after, if the duration is negative).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the
         semantics of the <code nobreak="false">-</code> operator when applied to an <code nobreak="false">xs:dateTime</code> and an
            <code nobreak="false">xs:yearMonthDuration</code> value. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-yearMonthDuration-from-dateTime" return-type="xs:dateTime" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dateTime"/><arg name="arg2" type="xs:yearMonthDuration"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the <code nobreak="false">xs:dateTime</code> computed by negating
               <code nobreak="false">$arg2</code> and adding the result to <code nobreak="false">$arg1</code> using the
            function <code nobreak="false">op:add-yearMonthDuration-to-dateTime</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-yearMonthDuration-from-dateTime(
  xs:dateTime("2000-10-30T11:12:00"),
  xs:yearMonthDuration("P1Y2M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime("1999-08-30T11:12:00")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-dayTimeDuration-from-dateTime"><head>op:subtract-dayTimeDuration-from-dateTime</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:dateTime</code> that is a given duration before a specified
               <code nobreak="false">xs:dateTime</code> (or after, if the duration is negative).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics
         of the <code nobreak="false">-</code> operator when applied to an <code nobreak="false">xs:dateTime</code> an and
            <code nobreak="false">xs:dayTimeDuration</code> values</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-dayTimeDuration-from-dateTime" return-type="xs:dateTime" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:dateTime"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>The function returns the <code nobreak="false">xs:dateTime</code> computed by negating
               <code nobreak="false">$arg2</code> and adding the result to <code nobreak="false">$arg1</code> using the
            function <code nobreak="false">op:add-dayTimeDuration-to-dateTime</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dayTimeDuration-from-dateTime(
  xs:dateTime("2000-10-30T11:12:00"),
  xs:dayTimeDuration("P3DT1H15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:dateTime("2000-10-27T09:57:00")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-add-yearMonthDuration-to-date"><head>op:add-yearMonthDuration-to-date</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:date</code> that is a given duration after a specified
               <code nobreak="false">xs:date</code> (or before, if the duration is negative).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics
         of the <code nobreak="false">+</code> operator when applied to an <code nobreak="false">xs:date</code> and an
            <code nobreak="false">xs:yearMonthDuration</code> value. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="add-yearMonthDuration-to-date" return-type="xs:date" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:date"/><arg name="arg2" type="xs:yearMonthDuration"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of casting <code nobreak="false">$arg1</code> to an
               <code nobreak="false">xs:dateTime</code>, adding <code nobreak="false">$arg2</code> using the function
               <code nobreak="false">op:add-yearMonthDuration-to-dateTime</code>, and casting the result back to an
               <code nobreak="false">xs:date</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:add-yearMonthDuration-to-date(
  xs:date("2000-10-30"),
  xs:yearMonthDuration("P1Y2M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2001-12-30")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-add-dayTimeDuration-to-date"><head>op:add-dayTimeDuration-to-date</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:date</code> that is a given duration after a specified
               <code nobreak="false">xs:date</code> (or before, if the duration is negative).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of
         the <code nobreak="false">+</code> operator when applied to an <code nobreak="false">xs:date</code> and an
            <code nobreak="false">xs:dayTimeDuration</code> value. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="add-dayTimeDuration-to-date" return-type="xs:date" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:date"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of casting <code nobreak="false">$arg1</code> to an
               <code nobreak="false">xs:dateTime</code>, adding <code nobreak="false">$arg2</code> using the function
               <code nobreak="false">op:add-dayTimeDuration-to-dateTime</code>, and casting the result back to an
               <code nobreak="false">xs:date</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:add-dayTimeDuration-to-date(
  xs:date("2004-10-30Z"),
  xs:dayTimeDuration("P2DT2H30M0S")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2004-11-01Z")</eg><p><emph>( The starting instant of the first argument is the
                  <code nobreak="false">xs:dateTime</code> value <code nobreak="false">{ 2004, 10, 30, 0, 0, 0, xs:dayTimeDuration("PT0S") }</code>.
                  Adding the second argument to this gives the <code nobreak="false">xs:dateTime</code> value
                  <code nobreak="false">{ 2004, 11, 1, 2, 30, 0, xs:dayTimeDuration("PT0S") }</code>. The time components are then
                  discarded. ).</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-yearMonthDuration-from-date"><head>op:subtract-yearMonthDuration-from-date</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:date</code> that is a given duration before a specified
               <code nobreak="false">xs:date</code> (or after, if the duration is negative).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics
         of the <code nobreak="false">-</code> operator when applied to an <code nobreak="false">xs:date</code> and an
            <code nobreak="false">xs:yearMonthDuration</code> value. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-yearMonthDuration-from-date" return-type="xs:date" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:date"/><arg name="arg2" type="xs:yearMonthDuration"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Returns the <code nobreak="false">xs:date</code> computed by negating <code nobreak="false">$arg2</code> and adding the
            result to <code nobreak="false">$arg1</code> using the function
               <code nobreak="false">op:add-yearMonthDuration-to-date</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-yearMonthDuration-from-date(
  xs:date("2000-10-30"),
  xs:yearMonthDuration("P1Y2M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("1999-08-30")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-yearMonthDuration-from-date(
  xs:date("2000-02-29Z"),
  xs:yearMonthDuration("P1Y")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("1999-02-28Z")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-yearMonthDuration-from-date(
  xs:date("2000-10-31-05:00"),
  xs:yearMonthDuration("P1Y1M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("1999-09-30-05:00")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-dayTimeDuration-from-date"><head>op:subtract-dayTimeDuration-from-date</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:date</code> that is a given duration before a specified
               <code nobreak="false">xs:date</code> (or after, if the duration is negative).</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of
         the <code nobreak="false">-</code> operator when applied to an <code nobreak="false">xs:date</code> and an
            <code nobreak="false">xs:dayTimeDuration</code>. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-dayTimeDuration-from-date" return-type="xs:date" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:date"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Returns the <code nobreak="false">xs:date</code> computed by negating <code nobreak="false">$arg2</code> and adding the
            result to <code nobreak="false">$arg1</code> using the function
               <code nobreak="false">op:add-dayTimeDuration-to-date</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dayTimeDuration-from-date(
  xs:date("2000-10-30"),
  xs:dayTimeDuration("P3DT1H15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:date("2000-10-26")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-add-dayTimeDuration-to-time"><head>op:add-dayTimeDuration-to-time</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:time</code> value that is a given duration after a specified
               <code nobreak="false">xs:time</code> (or before, if the duration is negative or causes wrap-around
            past midnight)</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of
         the <code nobreak="false">+</code> operator when applied to an <code nobreak="false">xs:time</code> and an
            <code nobreak="false">xs:dayTimeDuration</code> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="add-dayTimeDuration-to-time" return-type="xs:time" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:time"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Rules</label><def><p>First, the days component in the canonical lexical representation of <code nobreak="false">$arg2</code>
            is set to zero (0) and the value of the resulting <code nobreak="false">xs:dayTimeDuration</code> is
            calculated. Alternatively, the value of <code nobreak="false">$arg2</code> modulus 86,400 is used as the
            second argument. This value is added to the value of <code nobreak="false">$arg1</code> converted to an
               <code nobreak="false">xs:dateTime</code> using a reference date such as <code nobreak="false">1972-12-31</code>, and
            the time component of the result is returned. Note that the <code nobreak="false">xs:time</code>
            returned may occur in a following or preceding day and may be less than
               <code nobreak="false">$arg1</code>.</p><p>The result has the same timezone as <code nobreak="false">$arg1</code>. If <code nobreak="false">$arg1</code> has no
            timezone, the result has no timezone.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:add-dayTimeDuration-to-time(
  xs:time("11:12:00"),
  xs:dayTimeDuration("P3DT1H15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("12:27:00")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:add-dayTimeDuration-to-time(
  xs:time("23:12:00+03:00"),
  xs:dayTimeDuration("P1DT3H15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("02:27:00+03:00")</eg><p><emph>(That is, <code nobreak="false">{ 0, 0, 0, 2, 27, 0, xs:dayTimeDuration("PT3H") }</code>).</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-subtract-dayTimeDuration-from-time"><head>op:subtract-dayTimeDuration-from-time</head><glist><gitem><label>Summary</label><def><p>Returns the <code nobreak="false">xs:time</code> value that is a given duration before a specified
               <code nobreak="false">xs:time</code> (or after, if the duration is negative or causes wrap-around
            past midnight)</p></def></gitem><gitem><label>Operator Mapping</label><def><p>Defines the semantics of
         the <code nobreak="false">-</code> operator when applied to an <code nobreak="false">xs:time</code> and an
            <code nobreak="false">xs:dayTimeDuration</code> value. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="yes" prefix="op" name="subtract-dayTimeDuration-from-time" return-type="xs:time" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arg1" type="xs:time"/><arg name="arg2" type="xs:dayTimeDuration"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the result of negating <code nobreak="false">$arg2</code> and adding the result to
               <code nobreak="false">$arg1</code> using the function <code nobreak="false">op:add-dayTimeDuration-to-time</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dayTimeDuration-from-time(
  xs:time("11:12:00"),
  xs:dayTimeDuration("P3DT1H15M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("09:57:00")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">op:subtract-dayTimeDuration-from-time(
  xs:time("08:20:00-05:00"),
  xs:dayTimeDuration("P23DT10H10M")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:time("22:10:00-05:00")</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="formatting-dates-and-times"><head>Formatting dates and times</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:format-dateTime</code></td><td rowspan="1" colspan="1">Returns a string containing an <code nobreak="false">xs:dateTime</code> value formatted for display.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:format-date</code></td><td rowspan="1" colspan="1">Returns a string containing an <code nobreak="false">xs:date</code> value formatted for display.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:format-time</code></td><td rowspan="1" colspan="1">Returns a string containing an <code nobreak="false">xs:time</code> value formatted for display.</td></tr></tbody></table><p>Three functions are provided to represent dates and times as a string, using the conventions of a selected calendar,
 language, and country. The functions are presented in their customary fashion, 
 except for the rules and examples, which are described en bloc at <specref ref="rules-for-datetime-formatting"/>
               and <specref ref="date-time-examples"/>.</p><div3 id="func-format-dateTime"><head>fn:format-dateTime</head><changes><change issue="895" PR="901" date="2023-12-16">The 3rd, 4th, and 5th arguments are now optional; previously the function required either 2 or 5 arguments.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a string containing an <code nobreak="false">xs:dateTime</code> value formatted for display.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="format-dateTime" return-type="xs:string?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:dateTime?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?" default="()"/><arg name="calendar" type="xs:string?" default="()"/><arg name="place" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		default calendar, and default language, and default place, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>See <specref ref="rules-for-datetime-formatting"/>.</p></def></gitem></glist></div3><div3 id="func-format-date"><head>fn:format-date</head><changes><change issue="895" PR="901" date="2023-12-16">The 3rd, 4th, and 5th arguments are now optional; previously the function required either 2 or 5 arguments.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a string containing an <code nobreak="false">xs:date</code> value formatted for display.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="format-date" return-type="xs:string?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:date?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?" default="()"/><arg name="calendar" type="xs:string?" default="()"/><arg name="place" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		default calendar, and default language, and default place, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>See <specref ref="rules-for-datetime-formatting"/>.</p></def></gitem></glist></div3><div3 id="func-format-time"><head>fn:format-time</head><changes><change issue="895" PR="901" date="2023-12-16">The 3rd, 4th, and 5th arguments are now optional; previously the function required either 2 or 5 arguments.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a string containing an <code nobreak="false">xs:time</code> value formatted for display.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="format-time" return-type="xs:string?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:time?"/><arg name="picture" type="xs:string"/><arg name="language" type="xs:string?" default="()"/><arg name="calendar" type="xs:string?" default="()"/><arg name="place" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		default calendar, and default language, and default place, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>See <specref ref="rules-for-datetime-formatting"/>.</p></def></gitem></glist></div3><div3 id="rules-for-datetime-formatting"><head>The date/time formatting functions</head><p>The <function>fn:format-dateTime</function>, <function>fn:format-date</function>, 
and <function>fn:format-time</function> 
functions format <code nobreak="false">$value</code> as a string using 
the picture string specified by the <code nobreak="false">$picture</code> argument,
the calendar specified by the <code nobreak="false">$calendar</code> argument,
the language specified by the <code nobreak="false">$language</code> argument, 
and the country or other place name specified by the <code nobreak="false">$place</code> argument.
The result of the function is the formatted string representation of the supplied
  <code nobreak="false">xs:dateTime</code>, <code nobreak="false">xs:date</code>, or <code nobreak="false">xs:time</code> value.</p><p>
               <termdef id="dt-date-formatting-function" term="date formatting function">The three 
                  functions <function>fn:format-dateTime</function>, <function>fn:format-date</function>, 
                  and <function>fn:format-time</function> are referred to collectively as the
                   <term>date formatting functions</term>.</termdef>
            </p><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Calling the two-argument form of each of the three functions is equivalent
to calling the five-argument form with each of the last three arguments set to the empty sequence.</p><p>For details of the <code nobreak="false">$language</code>, <code nobreak="false">$calendar</code>, and
<code nobreak="false">$place</code> arguments, see <specref ref="lang-cal-place"/>.</p><p>In general, the use of an invalid <code nobreak="false">$picture</code>, 
<code nobreak="false">$language</code>, <code nobreak="false">$calendar</code>, or
               <code nobreak="false">$place</code> argument results in a dynamic error <errorref class="FD" code="1340"/>. By contrast,
use of an option in any of these arguments that is valid but not supported by the implementation is
not an error, and in these cases the implementation is required to output the value in a fallback
representation. More detailed rules are given below.</p><div4 id="date-picture-string"><head>The picture string</head><p>The picture consists of a sequence of variable markers and literal substrings.
A substring enclosed in square brackets is interpreted as a variable marker; substrings
not enclosed in square brackets are taken as literal substrings. 
The literal substrings are optional and if present are rendered unchanged, including any whitespace. 
If an opening or closing square bracket 
is required within a literal substring, it <rfc2119>must</rfc2119> be doubled.
The variable markers are replaced in the result by strings representing 
aspects of the date and/or time to be formatted. These are described in detail below.</p><p>A variable marker consists of a component specifier followed optionally 
by one or two presentation modifiers and/or optionally by a width modifier.
Whitespace within a variable marker is ignored.</p><p>The variable marker may be separated into its components
               by applying the following rules:</p><olist><item><p>The component specifier is always present and is always a
                  single letter.</p></item><item><p>The width modifier may be recognized by the presence of a comma.</p></item><item><p>The substring between the component specifier and the comma (if present)
                     or the end of the string (if there is no comma) contains the first and
                     second presentation modifiers, both of which are optional. If this substring
                  contains a single character, this is interpreted as the first presentation modifier.
                  If it contains more than one character, the last character is examined: if it is valid
                  as a second presentation modifier then it is treated as such, and the preceding part
                  of the substring constitutes the first presentation modifier. Otherwise, the second
                  presentation modifier is presumed absent and the whole substring is interpreted as the
                  first presentation modifier.</p></item></olist><p>The <emph>component specifier</emph> indicates the component of the date or
time that is required, and takes the following values:</p><table role="data"><thead><tr><th align="left" rowspan="1" colspan="1">Specifier</th><th align="left" rowspan="1" colspan="1">Meaning</th><th align="left" rowspan="1" colspan="1">Default Presentation Modifier</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">year (absolute value)</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">month in year</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">D</td><td rowspan="1" colspan="1">day in month</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">d</td><td rowspan="1" colspan="1">day in year</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">F</td><td rowspan="1" colspan="1">day of week</td><td rowspan="1" colspan="1">n</td></tr><tr><td rowspan="1" colspan="1">W</td><td rowspan="1" colspan="1">week in year</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">w</td><td rowspan="1" colspan="1">week in month</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">H</td><td rowspan="1" colspan="1">hour in day (24 hours)</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">h</td><td rowspan="1" colspan="1">hour in half-day (12 hours)</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">P</td><td rowspan="1" colspan="1">am/pm marker</td><td rowspan="1" colspan="1">n</td></tr><tr><td rowspan="1" colspan="1">m</td><td rowspan="1" colspan="1">minute in hour</td><td rowspan="1" colspan="1">01</td></tr><tr><td rowspan="1" colspan="1">s</td><td rowspan="1" colspan="1">second in minute</td><td rowspan="1" colspan="1">01</td></tr><tr><td rowspan="1" colspan="1">f</td><td rowspan="1" colspan="1">fractional seconds</td><td rowspan="1" colspan="1">1</td></tr><tr><td rowspan="1" colspan="1">Z</td><td rowspan="1" colspan="1">timezone</td><td rowspan="1" colspan="1">01:01</td></tr><tr><td rowspan="1" colspan="1">z</td><td rowspan="1" colspan="1">timezone (Same as Z, but modified where appropriate to include a prefix
                           as a time offset using GMT, for example GMT+1 or GMT-05:00. For this component there is a fixed
prefix of <code nobreak="false">GMT</code>, or a localized
variation thereof for the chosen language, and the remainder of the value is formatted as for specifier <code nobreak="false">Z</code>.)
                        </td><td rowspan="1" colspan="1">01:01</td></tr><tr><td rowspan="1" colspan="1">C</td><td rowspan="1" colspan="1">calendar: the name or abbreviation of a calendar name</td><td rowspan="1" colspan="1">n</td></tr><tr><td rowspan="1" colspan="1">E</td><td rowspan="1" colspan="1">era: the name of a baseline for the numbering of years, for example
                  the reign of a monarch</td><td rowspan="1" colspan="1">n</td></tr></tbody></table><p>A dynamic error is reported <errorref class="FD" code="1340"/>
 if the syntax of the picture is incorrect.</p><p>A dynamic error is reported <errorref class="FD" code="1350"/>
 if a component specifier within the picture 
 refers to components that are not available in the given type of <code nobreak="false">$value</code>,
 for example if the picture supplied to the <function>fn:format-time</function> refers
 to the year, month, or day component.</p><p>It is not an error to include a timezone component when the supplied
 value has no timezone. In these circumstances the timezone component will be ignored.</p><p>The first <emph>presentation modifier</emph> indicates the style in which the
value of a component is to be represented. Its value may be
either:</p><ulist><item><p>any format token permitted as a primary format token in the second argument 
of the <function>fn:format-integer</function> function, indicating
that the value of the component is to be output numerically using the specified number format (for example,
<code nobreak="false">1</code>, <code nobreak="false">01</code>, <code nobreak="false">i</code>, <code nobreak="false">I</code>, <code nobreak="false">w</code>, <code nobreak="false">W</code>,
or <code nobreak="false">Ww</code>) or </p></item><item><p>the format token <code nobreak="false">n</code>, <code nobreak="false">N</code>,
or <code nobreak="false">Nn</code>, indicating that the value of the component is to be output by name,
in lower-case, upper-case, or title-case respectively. Components that can be output by name
include (but are not limited to) months, days of the week, timezones, and eras. 
If the processor cannot output these components by name for the chosen calendar and language 
then it must use an <termref def="implementation-defined"/> fallback representation.</p></item></ulist><p>If a comma is to be used as a grouping separator within the format token, then there must be a width
			   specifier. More specifically: if a variable marker
			   contains one or more commas, then the last comma is treated as introducing the width modifier, and all others
			   are treated as grouping separators. So <code nobreak="false">[Y9,999,*]</code> will output the year as <code nobreak="false">2,008</code>.</p><p>It is not possible to use a closing square bracket as a grouping separator within the format token.</p><p>If the implementation does not support the use of the requested format token, it <rfc2119>must</rfc2119>
use the default presentation modifier for that component.</p><p>If the first presentation modifier is present, then it may optionally be followed by
a second presentation modifier as follows:</p><table role="longlastcol"><thead><tr><th align="left" rowspan="1" colspan="1">Modifier</th><th align="left" rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">either <code nobreak="false">a</code> or <code nobreak="false">t</code></td><td rowspan="1" colspan="1">indicates alphabetic or traditional numbering respectively,
                           the default being <termref def="implementation-defined"/>. 
                           This has the same meaning as in the second argument of <function>fn:format-integer</function>.</td></tr><tr><td rowspan="1" colspan="1">either <code nobreak="false">c</code> or <code nobreak="false">o</code></td><td rowspan="1" colspan="1">indicates cardinal or ordinal numbering respectively, for example
                           <code nobreak="false">7</code> or <code nobreak="false">seven</code> for a cardinal number, or <code nobreak="false">7th</code>,
                           <code nobreak="false">seventh</code>, or <code nobreak="false">7º</code>
                           for an ordinal number.
						This has the same meaning as
in the second argument of <function>fn:format-integer</function>. 
The actual representation of the ordinal form of a number
may depend not only on the language, but also on the grammatical context (for example,
in some languages it must agree in gender).</td></tr></tbody></table><note><p>Although the formatting rules are expressed in terms of the rules
for format tokens in <function>fn:format-integer</function>, the formats actually used may be specialized
to the numbering of date components where appropriate. For example, in Italian, it is conventional to
use an ordinal number (<code nobreak="false">primo</code>) for the first day of the month, and cardinal numbers
(<code nobreak="false">due, tre, quattro ...</code>) for the remaining days. A processor may therefore use
this convention to number days of the month, ignoring the presence or absence of the ordinal
presentation modifier.</p></note></div4><div4 id="width-modifier"><head>The Width Modifier</head><p>Whether or not a presentation modifier is included, a width modifier may be supplied. This
indicates the number of characters to be included in the representation of the value.</p><p>The width modifier, if present, is introduced by a comma. It takes the form:</p><p>
                  <code nobreak="false">   ","  min-width ("-" max-width)?</code>
               </p><p>where <code nobreak="false">min-width</code> is either an unsigned integer indicating the minimum number of characters to
be output, or <code nobreak="false">*</code> indicating that there is no explicit minimum, and 
<code nobreak="false">max-width</code> is either an unsigned integer indicating the maximum number of characters to
be output, or <code nobreak="false">*</code> indicating that there is no explicit maximum; if <code nobreak="false">max-width</code>
is omitted then <code nobreak="false">*</code> is assumed.</p><p>A dynamic error (<errorref class="FD" code="1340"/>) is raised if 
      <code nobreak="false">min-width</code> is present and less than one, or if
      <code nobreak="false">max-width</code> is present and less than one or less than <code nobreak="false">min-width</code>. 
   </p><p>A format token containing more than one digit, such as <code nobreak="false">001</code> or <code nobreak="false">9999</code>, sets the
minimum and maximum width to the number of digits appearing in the format token; if a width
modifier is also present, then the width modifier takes precedence.</p></div4><div4 id="formatting-integer-valued-components"><head>Formatting Integer-Valued Date/Time Components</head><p>The rules in this section apply to the majority of integer-valued components: specifically <code nobreak="false">M D d F W w H h m s</code>.</p><p>In the rules below, the term <term>decimal digit pattern</term> has the meaning given in <specref ref="func-format-integer"/>.</p><olist><item><p>If the first presentation modifier takes the form of a <term>decimal digit pattern</term>:</p><olist><item><p>If there is no width modifier, then the value is formatted according to 
		                      the rules of the <code nobreak="false">format-integer</code> function.</p></item><item><p>If there is a width modifier, then the first presentation modifier 
		                      is adjusted as follows:</p><olist><item><p>If the decimal digit pattern includes a grouping separator, the output is 
		                         implementation-defined (but this is not an error).
		                      </p><note><p>Use of a width modifier together with grouping separators is inadvisable 
		                            for this reason. It is never necessary to use a width modifier with a decimal 
		                            digit pattern, since the same effect can be achieved by use of optional digit signs.</p></note></item><item><p>Otherwise, the number of mandatory-digit-sign characters in the presentation 
		                         modifier is increased if necessary. This is done first by replacing optional-digit-signs 
		                         with mandatory-digit-signs, starting from the right, and then prepending mandatory-digit-signs 
		                         to the presentation modifier, until the number of mandatory-digit-signs is equal to the 
		                         minimum width. Any mandatory-digit-signs that are added by this process must use the 
		                         same decimal digit family as existing mandatory-digit-signs in the presentation modifier 
		                         if there are any, or ASCII digits otherwise.
		                      </p></item><item><p>The maximum width, if specified, is ignored.
		                      </p></item><item><p>The output is then as defined using the <code nobreak="false">format-integer</code> function with this adjusted decimal digit pattern.
		                      </p></item></olist></item></olist></item><item><p>If the first presentation modifiers is one of <code nobreak="false">N</code>, <code nobreak="false">n</code>, or <code nobreak="false">Nn</code>:</p><olist><item><p>Let <var>FN</var> be the full name of the component, that is, the form of the name 
		                     that would be used in the absence of any width modifier.</p></item><item><p>If <var>FN</var> is shorter than the minimum width, then it is padded by appending spaces to the end of the name.
		                  </p></item><item><p>If <var>FN</var> is longer than the maximum width, then it is abbreviated, either 
		                     by choosing a conventional abbreviation that fits within the maximum width (for example, 
		                     “Wednesday” might be abbreviated to “Weds”), or by removing characters from the end 
		                     of <var>FN</var> until it fits within the maximum width.
		                  </p></item></olist></item><item><p>For other presentation modifiers:</p><olist><item><p>Any adjustment of the value to fit within the requested width range is implementation-defined. </p></item><item><p>The value should not be truncated if this results in output that will not be meaningful to users (for example, 
		                     there is no sensible way to truncate Roman numerals).</p></item><item><p>If shorter than the minimum width, the value should be padded to the minimum width, either by appending spaces, 
		                     or in some other way appropriate to the numbering scheme.</p></item></olist></item></olist></div4><div4 id="formatting-year-component"><head>Formatting the Year Component</head><p>The rules for the year component (Y) are the same as those in <specref ref="formatting-integer-valued-components"/>, 
		            except that the value of the year as output is the value of the year component of the supplied value modulo ten to the power 
		            <var>N</var> where <var>N</var> is determined as follows: 
		         </p><olist><item><p>If the width modifier is present and defines a finite maximum width, then that maximum width.
		            </p></item><item><p>Otherwise, if the first presentation modifier takes the form of a decimal-digit-pattern, 
		               then:</p><olist><item><p>Let <var>W</var> be the number of optional-digit-signs and mandatory-digit-signs in that decimal-digit-pattern.</p></item><item><p>If <var>W</var> is 2 or more, then <var>W</var>.</p></item></olist></item><item><p>Otherwise, <var>N</var> is infinity (that is, the year is output in full).</p></item></olist></div4><div4 id="formatting-fractional-seconds"><head>Formatting Fractional Seconds</head><p>The output for the fractional seconds component (<code nobreak="false">f</code>) is equivalent to the result of the following algorithm: </p><olist><item><p>If the first presentation modifier contains no Unicode digit, then the output is implementation-defined.
		            </p></item><item><p>Otherwise, the value of the fractional seconds is output as follows:</p><olist><item><p>If there is no width modifier and the first presentation modifier comprises in its
		                  entirety a single mandatory-digit-sign (for example the default <code nobreak="false">1</code>), then
		                  the presentation modifier is extended on the right with as many optional-digit-signs as
		                  are needed to accommodate the actual fractional seconds precision encountered in the
		                  value to be formatted.
		               </p></item><item><p>If there is a width modifier, then the first presentation modifier 
		                  is adjusted as follows:</p><olist><item><p>If a minimum width is specified, and if this exceeds the number of mandatory-digit-sign characters 
		                        in the first presentation modifier, then the first presentation modifier is adjusted. 
		                        This is done first by replacing optional-digit-signs 
		                        with mandatory-digit-signs, starting from the left, and then appending mandatory-digit-signs 
		                        to the presentation modifier, until the number of mandatory-digit-signs is equal to the 
		                        minimum width. Any mandatory-digit-signs that are added by this process must use the 
		                        same decimal digit family as existing mandatory-digit-signs in the presentation modifier.
		                     </p></item><item><p>If a maximum width is specified, the first presentation modifier is extended on the right
		                        with as many optional-digit-signs as are needed to ensure that the number of mandatory-digit-signs
		                        and optional-digit-signs is at least equal to the maximum width.
		                     </p></item></olist></item><item><p>The sequence of characters in the (adjusted) first presentation modifier is reversed (for example, 
		                  <code nobreak="false">999'###</code> becomes <code nobreak="false">###'999</code>). 
		                  If the result is not a valid <term>decimal digit pattern</term>, then the output is 
		                  <termref def="implementation-defined">implementation-defined</termref>.
		               </p></item><item><p>The sequence of digits in the conventional decimal representation of the fractional seconds component 
		                  is reversed, with insignificant zeroes removed, and the result is treated as an integer. For example, if the 
		                  seconds value is <code nobreak="false">25.8235</code>, the reversed fractional seconds value is <code nobreak="false">5328</code>.
		               </p></item><item><p>The reversed fractional seconds value is formatted using the reversed decimal digit pattern according to the 
		                  rules of the <function>fn:format-integer</function> function. Given the examples above, the result is <code nobreak="false">5'328</code>
		               </p></item><item><p>The resulting string is reversed. In our example, the result is <code nobreak="false">823'5</code>.</p></item><item><p>If the result contains more digits than the number of mandatory-digit-signs and optional-digit-signs in the 
		                  decimal digit pattern, then excess digits 
		                  are removed from the right hand end (that is, the value is truncated towards zero rather than being rounded). 
		                  Any grouping separator that immediately precedes a removed digit 
		                  is also removed.</p></item></olist></item></olist><note><p>The reason for presenting the algorithm in this way is that it enables maximum reuse of the rules defined for
		            <function>fn:format-integer</function>. Since the fractional seconds value is not properly an integer, the rules do not
		            work if used directly: for example, the positions of grouping separators need to be counted from the left rather
		            than from the right. Implementations, as always, are free to use a different algorithm that yields the same result.</p></note><note><p>A format token consisting of a single digit,
		            such as <code nobreak="false">1</code>, does not constrain the number of digits in the output. 
		            In the case of fractional seconds in particular, <code nobreak="false">[f001]</code> requests three decimal digits,
		            <code nobreak="false">[f01]</code> requests two digits, but <code nobreak="false">[f1]</code> will retain all digits in the
		            supplied date/time value (the maximum number of digits is implementation-defined). 
		            If exactly one digit is required, this can be achieved using the component specifier 
		            <code nobreak="false">[f1,1-1]</code>.</p></note></div4><div4 id="formatting-timezones"><head>Formatting timezones</head><p>Special rules apply to the formatting of timezones. When the component specifiers <code nobreak="false">Z</code>
		      or <code nobreak="false">z</code> are used, the rules in this section override any rules given elsewhere in the case of
		      discrepancies.</p><p>If the date/time value to be formatted does not include a timezone offset, then the timezone component
		      specifier is generally ignored (results in no output). The exception is where military timezones are used
		      (format <code nobreak="false">ZZ</code>) in which case the string <code nobreak="false">"J"</code> is output, indicating local time.</p><ulist><item><p>When the component specifier is <code nobreak="false">z</code>, the output is the same as for component specifier
		      <code nobreak="false">Z</code>, except that it is prefixed by the characters <code nobreak="false">GMT</code> or some localized
		      equivalent. The prefix is omitted, however, in cases where the timezone is identified by name rather than by
		      a numeric offset from UTC.</p></item><item><p>If the first <var>presentation modifier</var> is numeric and comprises one or two digits 
		         with no <var>grouping-separator</var> (for example <code nobreak="false">1</code>
		      or <code nobreak="false">01</code>), then the timezone is formatted as a displacement from UTC in hours, preceded by a plus or minus
		      sign: for example <code nobreak="false">-5</code> or <code nobreak="false">+03</code>. If the actual timezone offset is not an integral number of hours,
		      then the minutes part of the offset is appended, separated by a colon: for example <code nobreak="false">+10:30</code> or 
		         <code nobreak="false">-1:15</code>.</p></item><item><p>If the first <var>presentation modifier</var> is numeric with a <var>grouping-separator</var> (for example <code nobreak="false">1:01</code>
		         or <code nobreak="false">01.01</code>), then the timezone offset is output in hours and minutes, separated by the grouping separator,
		      even if the number of minutes is zero: for example <code nobreak="false">+5:00</code> or <code nobreak="false">+10.30</code>.</p></item><item><p>If the first <var>presentation modifier</var> is numeric and comprises three or four digits with no
		      <var>grouping-separator</var>, for example <code nobreak="false">001</code> or <code nobreak="false">0001</code>, then the timezone offset
		      is shown in hours and minutes with no separator, for example <code nobreak="false">-0500</code> or <code nobreak="false">+1030</code>.
		      </p></item><item><p>If the first <var>presentation modifier</var> is numeric, in any of the above formats, and the second
		      <var>presentation modifier</var> is <code nobreak="false">t</code>, then a zero timezone offset (that is, UTC) is output as <code nobreak="false">Z</code> instead
		      of a signed numeric value. In this presentation modifier is absent or if the timezone offset is non-zero, 
		      then the displayed timezone offset is preceded by a <code nobreak="false">-</code> sign for negative offsets
		      or a <code nobreak="false">+</code> sign for non-negative offsets.</p></item><item><p>If the first <var>presentation modifier</var> is <code nobreak="false">Z</code>, then the timezone is formatted
		         as a military timezone letter, using the convention Z = +00:00, A = +01:00, B = +02:00, ..., M = +12:00, 
		         N = -01:00, O = -02:00, ... Y = -12:00. The letter J (meaning local time) is used in the case of a 
		         value that does not specify a timezone offset. Timezone offsets that have no representation in this system
		         (for example Indian Standard Time, +05:30) are output as if the format <code nobreak="false">01:01</code> had been requested.</p></item><item><p>If the first <var>presentation modifier</var> is <code nobreak="false">N</code>, then the timezone is output
		      (where possible) as a timezone name, for example <code nobreak="false">EST</code> or <code nobreak="false">CET</code>. The same timezone
		      offset has different names in different places; it is therefore <rfc2119>recommended</rfc2119> that this option
		      should be used only if a country code (see <bibref ref="ISO3166"/>) or IANA timezone name (see <bibref ref="olson"/>) is supplied in the <code nobreak="false">$place</code> argument.
		      In the absence of this information, the implementation may apply a default, for example by using the timezone
		      names that are conventional in North America. If no timezone name can be identified, the timezone offset is
		      output using the fallback format <phrase diff="chg" at="2023-04-24"><code nobreak="false">01:01</code></phrase>.</p></item></ulist><p>The following examples illustrate options for timezone formatting.</p><table role="small complex data"><thead><tr><th rowspan="1" colspan="1">Variable marker</th><th rowspan="1" colspan="1"><code nobreak="false">$place</code></th><th colspan="5" rowspan="1">Timezone offsets (with time = 12:00:00)</th></tr><tr><th rowspan="1" colspan="1"> </th><th rowspan="1" colspan="1"> </th><th rowspan="1" colspan="1">-10:00</th><th rowspan="1" colspan="1">-05:00</th><th rowspan="1" colspan="1">+00:00</th><th rowspan="1" colspan="1">+05:30</th><th rowspan="1" colspan="1">+13:00</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">[Z]</td><td rowspan="1" colspan="1">()</td><td rowspan="1" colspan="1">-10:00</td><td rowspan="1" colspan="1">-05:00</td><td rowspan="1" colspan="1">+00:00</td><td rowspan="1" colspan="1">+05:30</td><td rowspan="1" colspan="1">+13:00</td></tr><tr><td rowspan="1" colspan="1">[Z0]</td><td rowspan="1" colspan="1">()</td><td rowspan="1" colspan="1">-10</td><td rowspan="1" colspan="1">-5</td><td rowspan="1" colspan="1">+0</td><td rowspan="1" colspan="1">+5:30</td><td rowspan="1" colspan="1">+13</td></tr><tr><td rowspan="1" colspan="1">[Z0:00]</td><td rowspan="1" colspan="1">()</td><td rowspan="1" colspan="1">-10:00</td><td rowspan="1" colspan="1">-5:00</td><td rowspan="1" colspan="1">+0:00</td><td rowspan="1" colspan="1">+5:30</td><td rowspan="1" colspan="1">+13:00</td></tr><tr><td rowspan="1" colspan="1">[Z00:00]</td><td rowspan="1" colspan="1">()</td><td rowspan="1" colspan="1">-10:00</td><td rowspan="1" colspan="1">-05:00</td><td rowspan="1" colspan="1">+00:00</td><td rowspan="1" colspan="1">+05:30</td><td rowspan="1" colspan="1">+13:00</td></tr><tr><td rowspan="1" colspan="1">[Z0000]</td><td rowspan="1" colspan="1">()</td><td rowspan="1" colspan="1">-1000</td><td rowspan="1" colspan="1">-0500</td><td rowspan="1" colspan="1">+0000</td><td rowspan="1" colspan="1">+0530</td><td rowspan="1" colspan="1">+1300</td></tr><tr><td rowspan="1" colspan="1">[Z00:00t]</td><td rowspan="1" colspan="1">()</td><td rowspan="1" colspan="1">-10:00</td><td rowspan="1" colspan="1">-05:00</td><td rowspan="1" colspan="1">Z</td><td rowspan="1" colspan="1">+05:30</td><td rowspan="1" colspan="1">+13:00</td></tr><tr><td rowspan="1" colspan="1">[z]</td><td rowspan="1" colspan="1">()</td><td rowspan="1" colspan="1">GMT‑10:00</td><td rowspan="1" colspan="1">GMT‑05:00</td><td rowspan="1" colspan="1">GMT+00:00</td><td rowspan="1" colspan="1">GMT+05:30</td><td rowspan="1" colspan="1">GMT+13:00</td></tr><tr><td rowspan="1" colspan="1">[ZZ]</td><td rowspan="1" colspan="1">()</td><td rowspan="1" colspan="1">W</td><td rowspan="1" colspan="1">R</td><td rowspan="1" colspan="1">Z</td><td rowspan="1" colspan="1">+05:30</td><td rowspan="1" colspan="1">+13:00</td></tr><tr><td rowspan="1" colspan="1">[ZN]</td><td rowspan="1" colspan="1">"us"</td><td rowspan="1" colspan="1">HST</td><td rowspan="1" colspan="1">EST</td><td rowspan="1" colspan="1">GMT</td><td rowspan="1" colspan="1">IST</td><td rowspan="1" colspan="1">+13:00</td></tr><tr><td rowspan="1" colspan="1">[H00]:[M00] [ZN]</td><td rowspan="1" colspan="1">"America/New_York"</td><td rowspan="1" colspan="1">06:00 EST</td><td rowspan="1" colspan="1">12:00 EST</td><td rowspan="1" colspan="1">07:00 EST</td><td rowspan="1" colspan="1">01:30 EST</td><td rowspan="1" colspan="1">18:00 EST</td></tr></tbody></table><p>If a width specifier is present when formatting a timezone, then the representation as defined in this section is padded to the minimum
		      width as described in <specref ref="width-modifier"/>, but it is never shortened.</p></div4><div4 id="formatting-other-components"><head>Formatting Other Components</head><p>This section applies to the remaining components: <code nobreak="false">P</code> (am/pm marker), <code nobreak="false">C</code> (calendar),
		      and <code nobreak="false">E</code> (era).</p><p>The output for these components is entirely <termref def="implementation-defined">implementation-defined</termref>.
		      The default presentation modifier for these components is <code nobreak="false">n</code>, indicating that they are output as names (or
		      conventional abbreviations), and the chosen names will in many cases depend on the chosen language: see <specref ref="lang-cal-place"/>.</p></div4><div4 id="lang-cal-place"><head>The language, calendar, and place arguments</head><p>The set of languages, calendars, and places that are supported in the 
<termref def="dt-date-formatting-function">date formatting functions</termref> is
<termref def="implementation-defined">implementation-defined</termref>. When
any of these arguments is omitted or is the empty sequence, an <termref def="implementation-defined">implementation-defined</termref>
default value is used.</p><imp-def-feature>The set of languages, calendars, and places that are supported in the 
<termref def="dt-date-formatting-function">date formatting functions</termref> is
implementation-defined. If any of these arguments is omitted or set to the empty sequence, 
the default is implementation-defined.</imp-def-feature><p>If the fallback representation uses a different calendar from that requested,
the output string <rfc2119>must</rfc2119> identify the calendar actually used, for example by
prefixing the string with <code nobreak="false">[Calendar: X]</code> (where X is the calendar actually used),
localized as appropriate to the
requested language. If the fallback representation uses a different language
from that requested, the output string <rfc2119>must</rfc2119> identify the language actually
used, for example by prefixing the string with <code nobreak="false">[Language: Y]</code> (where Y is the language
actually used) localized in an
implementation-dependent way. If a particular component of the value cannot be output in
the requested format, it <rfc2119>should</rfc2119> be output in the default format for
that component.</p><p>The <code nobreak="false">$language</code> argument specifies the language to be used for the result string 
of the function. The value of the argument <rfc2119>should</rfc2119> be either the empty sequence
or a value that would be valid for the <code nobreak="false">xml:lang</code> attribute (see <bibref ref="xml"/>).
Note that this permits the identification of sublanguages
based on country codes (from <bibref ref="ISO3166"/>) as well as identification of dialects
and of regions within a country.</p><p>If the <code nobreak="false">$language</code> 
argument is omitted or is set to the empty sequence, or if it is set to an invalid value or a
value that the implementation does not recognize, 
then the processor uses the default language defined in the dynamic context.</p><p>The language is used to select the appropriate language-dependent forms of:</p><ulist><item><p>names (for example, of months)</p></item><item><p>numbers expressed as words or as ordinals (<code nobreak="false">twenty, 20th, twentieth</code>)</p></item><item><p>hour convention (0-23 vs 1-24, 0-11 vs 1-12)</p></item><item><p>first day of week, first week of year</p></item></ulist><p>Where appropriate this choice may also take into account the value of the
<code nobreak="false">$place</code> argument, though this <rfc2119>should</rfc2119> not be used to override the
language or any sublanguage that is specified as part of the <code nobreak="false">language</code>
argument.</p><p>The choice of the names and abbreviations used in any given language is 
<termref def="implementation-defined">implementation-defined</termref>. For example,
one implementation might abbreviate July as <code nobreak="false">Jul</code> while another uses <code nobreak="false">Jly</code>. In German,
one implementation might represent Saturday as <code nobreak="false">Samstag</code> while another
uses <code nobreak="false">Sonnabend</code>. Implementations <rfc2119>may</rfc2119> provide mechanisms allowing users to
control such choices.</p><imp-def-feature>The choice of the names and abbreviations used in any given language for
calendar units such as days of the week and months of the year is 
<termref def="implementation-defined">implementation-defined</termref>.</imp-def-feature><p>Where ordinal numbers are used, the selection of the correct representation of the 
ordinal (for example, the grammatical gender) <rfc2119>may</rfc2119> depend on the component being formatted and on its
textual context in the picture string.</p><p>The <code nobreak="false">calendar</code> attribute specifies that the <code nobreak="false">dateTime</code>, <code nobreak="false">date</code>,
or <code nobreak="false">time</code> supplied in the <code nobreak="false">$value</code> argument <rfc2119>must</rfc2119> be 
converted to a value in the specified calendar and then converted to a string using the 
conventions of that calendar.</p><p>The calendar value if present <rfc2119>must</rfc2119> be a valid <code nobreak="false">EQName</code> 
                  (dynamic error: <errorref class="FD" code="1340"/>).
                  If it is a lexical <code nobreak="false">QName</code> then it is expanded into an expanded QName 
                     using the statically known namespaces; if it has no prefix then it represents an expanded-QName in no namespace.
                  If the expanded QName is in no namespace, 
                  then it <rfc2119>must</rfc2119> identify a calendar with a designator specified below 
                  (dynamic error: <errorref class="FD" code="1340"/>). 
If the expanded QName is in a namespace then it identifies the calendar in an <termref def="implementation-defined">implementation-defined</termref> way.</p><p>If the <code nobreak="false">$calendar</code> argument is omitted or is set to the empty sequence
                  then the default calendar defined in the dynamic context is used.</p><note><p>The calendars listed below were known to be in use during the 
last hundred years. Many other calendars have been used in the past.</p><p>This specification does not define any of these calendars, nor the way that they
map to the value space of the <code nobreak="false">xs:date</code> datatype in <bibref ref="xmlschema-2"/>.
There may be ambiguities when dates are recorded using different calendars. 
For example, the start of a new day is not simultaneous in different calendars, 
and may also vary geographically (for example, based on the time of sunrise or sunset).
Translation of dates is therefore more reliable when the time of day is also known, and
when the geographic location is known. 
When translating dates between
one calendar and another, the processor may take account of the values
of the <code nobreak="false">$place</code> and/or <code nobreak="false">$language</code> arguments, with the 
                     <code nobreak="false">$place</code>
argument taking precedence.</p><p>Information about some of these calendars, and algorithms for converting between them, may
be found in <bibref ref="CALCALC"/>.</p></note><table role="data"><thead><tr><th rowspan="1" colspan="1">Designator</th><th rowspan="1" colspan="1">Calendar</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">AD</td><td rowspan="1" colspan="1">Anno Domini (Christian Era)</td></tr><tr><td rowspan="1" colspan="1">AH</td><td rowspan="1" colspan="1">Anno Hegirae (Islamic Era)</td></tr><tr><td rowspan="1" colspan="1">AME</td><td rowspan="1" colspan="1">Mauludi Era (solar years since Muhammad’s birth)</td></tr><tr><td rowspan="1" colspan="1">AM</td><td rowspan="1" colspan="1">Anno Mundi (Jewish Calendar)</td></tr><tr><td rowspan="1" colspan="1">AP</td><td rowspan="1" colspan="1">Anno Persici</td></tr><tr><td rowspan="1" colspan="1">AS</td><td rowspan="1" colspan="1">Aji Saka Era (Java)</td></tr><tr><td rowspan="1" colspan="1">BE</td><td rowspan="1" colspan="1">Buddhist Era</td></tr><tr><td rowspan="1" colspan="1">CB</td><td rowspan="1" colspan="1">Cooch Behar Era</td></tr><tr><td rowspan="1" colspan="1">CE</td><td rowspan="1" colspan="1">Common Era</td></tr><tr><td rowspan="1" colspan="1">CL</td><td rowspan="1" colspan="1">Chinese Lunar Era</td></tr><tr><td rowspan="1" colspan="1">CS</td><td rowspan="1" colspan="1">Chula Sakarat Era</td></tr><tr><td rowspan="1" colspan="1">EE</td><td rowspan="1" colspan="1">Ethiopian Era</td></tr><tr><td rowspan="1" colspan="1">FE</td><td rowspan="1" colspan="1">Fasli Era</td></tr><tr><td rowspan="1" colspan="1">ISO</td><td rowspan="1" colspan="1">ISO 8601 calendar</td></tr><tr><td rowspan="1" colspan="1">JE</td><td rowspan="1" colspan="1">Japanese Calendar</td></tr><tr><td rowspan="1" colspan="1">KE</td><td rowspan="1" colspan="1">Khalsa Era (Sikh calendar)</td></tr><tr><td rowspan="1" colspan="1">KY</td><td rowspan="1" colspan="1">Kali Yuga</td></tr><tr><td rowspan="1" colspan="1">ME</td><td rowspan="1" colspan="1">Malabar Era</td></tr><tr><td rowspan="1" colspan="1">MS</td><td rowspan="1" colspan="1">Monarchic Solar Era</td></tr><tr><td rowspan="1" colspan="1">NS</td><td rowspan="1" colspan="1">Nepal Samwat Era</td></tr><tr><td rowspan="1" colspan="1">OS</td><td rowspan="1" colspan="1">Old Style (Julian Calendar)</td></tr><tr><td rowspan="1" colspan="1">RS</td><td rowspan="1" colspan="1">Rattanakosin (Bangkok) Era</td></tr><tr><td rowspan="1" colspan="1">SE</td><td rowspan="1" colspan="1">Saka Era</td></tr><tr><td rowspan="1" colspan="1">SH</td><td rowspan="1" colspan="1">Solar Hijri (Islamic Era, used in Iran and Afghanistan)</td></tr><tr><td rowspan="1" colspan="1">SS</td><td rowspan="1" colspan="1">Saka Samvat</td></tr><tr><td rowspan="1" colspan="1">TE</td><td rowspan="1" colspan="1">Tripurabda Era</td></tr><tr><td rowspan="1" colspan="1">VE</td><td rowspan="1" colspan="1">Vikrama Era</td></tr><tr><td rowspan="1" colspan="1">VS</td><td rowspan="1" colspan="1">Vikrama Samvat Era</td></tr></tbody></table><p>At least one of the above calendars <rfc2119>must</rfc2119> be supported. It is 
<termref def="implementation-defined">implementation-defined</termref> which
calendars are supported.</p><p>The ISO 8601 calendar (<bibref ref="ISO8601"/>), 
which is included in the above list and designated <code nobreak="false">ISO</code>, 
is very similar to the Gregorian calendar designated <code nobreak="false">AD</code>, but it
differs in several ways. The ISO calendar
    is intended to ensure that date and time formats can be read
    easily by other software, as well as being legible for human
    users. The ISO calendar
prescribes the use of particular numbering conventions as defined in
ISO 8601, rather than allowing these to be localized on a per-language basis. 
In particular it
    provides a numeric “week date” format which identifies dates by
    year, week of the year, and day in the week; 
in the ISO calendar the days of the week are numbered from 1 (Monday) to 7 (Sunday), and
week 1 in any calendar year is the week (from Monday to Sunday) that includes the first Thursday
of that year. The numeric values of the components year, month, day, hour, minute, and second
are the same in the ISO calendar as the values used in the lexical representation of the date and
time as defined in <bibref ref="xmlschema-2"/>. The era (<code nobreak="false">E</code> component)
with this calendar is either a minus sign (for negative years) or a zero-length string (for positive years).
For dates before 1 January, AD 1, year numbers in
    the ISO and AD calendars are off by one from each other: ISO year
    0000 is 1 BC, -0001 is 2 BC, etc.</p><p>ISO 8601 does not define a numbering for weeks within a month. When the <code nobreak="false">w</code>
               component is used, the convention to be adopted is that each Monday-to-Sunday week is considered to
               fall within a particular month if its Thursday occurs in that month; the weeks that fall in a particular
               month under this definition are numbered starting from 1. Thus, for example, 
               29 January 2013 falls in week 5 because the Thursday of the week (31 January 2013) is the fifth Thursday
               in January, and 1 February 2013 is also in week 5 for the same reason.</p><note><p>The value space of the date and time datatypes, as defined in XML Schema, is based on
absolute points in time. The lexical space of these datatypes defines a 
representation of these absolute points in time using the proleptic Gregorian calendar,
that is, the modern Western calendar extrapolated into the past and the future; but the value space
is calendar-neutral. The
<termref def="dt-date-formatting-function">date formatting functions</termref> produce a representation
of this absolute point in time, but denoted in a possibly different calendar. So,
for example, the date whose lexical representation in XML Schema is <code nobreak="false">1502-01-11</code> 
(the day on which Pope Gregory XIII was born) might be
formatted using the Old Style (Julian) calendar as <code nobreak="false">1 January 1502</code>. This reflects the fact
that there was at that time a ten-day difference between the two calendars. It would be
incorrect, and would produce incorrect results, to represent this date in an element or attribute 
of type <code nobreak="false">xs:date</code> as <code nobreak="false">1502-01-01</code>, even though this might reflect the way 
the date was recorded in contemporary documents.</p><p>When referring to years occurring in antiquity, modern historians generally
use a numbering system in which there is no year zero (the year before 1 CE
is thus 1 BCE). This is the convention that <rfc2119>should</rfc2119> be used when the
requested calendar is OS (Julian) or AD (Gregorian). When the requested
calendar is ISO, however, the conventions of ISO 8601 <rfc2119>should</rfc2119> be followed:
here the year before +0001 is numbered zero. In <bibref ref="xmlschema-2"/> (version 1.0), 
the value space for <code nobreak="false">xs:date</code> and <code nobreak="false">xs:dateTime</code>
does not include a year zero: however, XSD 1.1 endorses the ISO 8601 convention. This means that the date on
which Julius Caesar was assassinated has the ISO 8601 lexical representation
-0043-03-13, but will be formatted as 15 March 44 BCE in the Julian calendar
or 13 March 44 BCE in the Gregorian calendar (dependent on the chosen
localization of the names of months and eras).</p></note><p>The intended use of the <code nobreak="false">$place</code> argument is to identify
 the place where an event
represented by the <code nobreak="false">dateTime</code>, <code nobreak="false">date</code>,
or <code nobreak="false">time</code> supplied in the <code nobreak="false">$value</code> argument took place or will take place.
                  If the <code nobreak="false">$place</code> argument is omitted or is set
                  to the empty sequence, then the default place defined in the dynamic context is used.
If the value is supplied, and is not the empty sequence, then it <rfc2119>should</rfc2119> 
                  either be a country code or an IANA timezone name.
               If the value does not take this form, or if its value is not recognized
               by the implementation, then the default place defined in the dynamic context is used.</p><ulist><item><p>Country codes are defined in <bibref ref="ISO3166"/>. Examples are <code nobreak="false">"de"</code> for Germany
      and <code nobreak="false">"jp"</code> for Japan. Implementations <rfc2119>may</rfc2119> also allow the use
of codes representing subdivisions of a country from ISO 3166-2, or codes representing formerly used names of
countries from ISO 3166-3</p></item><item><p>IANA timezone names are defined in the IANA timezone database <bibref ref="olson"/>.
   Examples are <code nobreak="false">"America/New_York"</code> and <code nobreak="false">"Europe/Rome"</code>.</p></item></ulist><p>This argument is not intended to identify the location of the user 
for whom the date or time is being formatted;
that should be done by means of the <code nobreak="false">$language</code> attribute. 
This information 
<rfc2119>may</rfc2119> be used to provide additional information when converting dates between
calendars or when deciding how individual components of the date and time are to be formatted. 
For example, different countries using the Old Style (Julian) calendar started the new year on different
days, and some countries used variants of the calendar that were out of synchronization as a result of
differences in calculating leap years.</p><p>The geographical area identified by a country code is defined by the
  boundaries as they existed at the time of the date to be formatted,
  or the present-day boundaries for dates in the future.</p><p>If the <code nobreak="false">$place</code> argument is supplied in the form
                  of an IANA timezone name that is recognized by the implementation, then the date or
               time being formatted is adjusted to the timezone offset applicable in that timezone.
               For example, if the <code nobreak="false">xs:dateTime</code> value <code nobreak="false">2010-02-15T12:00:00Z</code>
                  is formatted with the <code nobreak="false">$place</code> argument set to
                  <code nobreak="false">America/New_York</code>, then the output will be as if the value
                  <code nobreak="false">2010-02-15T07:00:00-05:00</code> had been supplied. This adjustment takes daylight
                  savings time into account where possible; if the date in question falls during
                  daylight savings time in New York, then it is adjusted to timezone offset <code nobreak="false">-PT4H</code>
                  rather than <code nobreak="false">-PT5H</code>. Adjustment using daylight savings time is only possible
                  where the value includes a date, and where the date is within the range covered
                  by the timezone database.</p></div4></div3><div3 id="date-time-examples"><head>Examples of date and time formatting</head><p>The following examples show a selection of dates and times and the way they might
be formatted. These examples assume the use of the Gregorian calendar as the default calendar.</p><table role="data"><thead><tr><th rowspan="1" colspan="1">Required Output</th><th rowspan="1" colspan="1">Expression</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">2002-12-31</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[Y0001]-[M01]-[D01]")</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">12-31-2002</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[M]-[D]-[Y]")</code>
                           </td></tr><tr><td rowspan="1" colspan="1"> 
                              <code nobreak="false">31-12-2002</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D]-[M]-[Y]")</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">31 XII 2002</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D1] [MI] [Y]")</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">31st December, 2002</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D1o] [MNn], [Y]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">31 DEC 2002</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D01] [MN,*-3] [Y0001]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">December 31, 2002</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[MNn] [D], [Y]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">31 Dezember, 2002</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D] [MNn], [Y]", "de", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">Tisdag 31 December 2002</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[FNn] [D] [MNn] [Y]", "sv", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">[2002-12-31]</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[[[Y0001]-[M01]-[D01]]]")</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">Two Thousand and Three</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[YWw]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">einunddreißigste Dezember</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[Dwo] [MNn]", "de", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">3:58 PM</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-time($t, "[h]:[m01] [PN]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">3:58:45 pm</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-time($t, "[h]:[m01]:[s01] [Pn]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">3:58:45 PM PDT</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-time($t, "[h]:[m01]:[s01] [PN] [ZN,*-3]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">3:58:45 o'clock PM PDT</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-time($t, "[h]:[m01]:[s01] o'clock [PN] [ZN,*-3]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">15:58</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-time($t, "[H01]:[m01]")</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">15:58:45.762</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-time($t, "[H01]:[m01]:[s01].[f001]")</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">15:58:45 GMT+02:00</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-time($t, "[H01]:[m01]:[s01] [z,6-6]", "en", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">15.58 Uhr GMT+2</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-time($t, "[H01]:[m01] Uhr [z]", "de", (), ())</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">3.58pm on Tuesday, 31st December</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-dateTime($dt, "[h].[m01][Pn] on [FNn], [D1o] [MNn]")</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                              <code nobreak="false">12/31/2002 at 15:58:45</code>
                           </td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-dateTime($dt, "[M01]/[D01]/[Y0001] at [H01]:[m01]:[s01]")</code>
                           </td></tr></tbody></table><p>The following examples use calendars other than the Gregorian calendar.</p><table role="data"><thead><tr><th rowspan="1" colspan="1">Description</th><th rowspan="1" colspan="1">Request</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">Islamic</td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D&amp;#x0661;] [Mn] [Y&amp;#x0661;]", "ar", "AH", ())</code>
                           </td><td rowspan="1" colspan="1">٢٦ ﺸﻭّﺍﻝ ١٤٢٣</td></tr><tr><td rowspan="1" colspan="1">Jewish (with Western numbering)</td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D] [Mn] [Y]", "he", "AM", ())</code>
                           </td><td rowspan="1" colspan="1">‏26 טבת 5763</td></tr><tr><td rowspan="1" colspan="1">Jewish (with traditional numbering)</td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D&amp;#x05D0;t] [Mn] [Y&amp;#x05D0;t]", "he", "AM", ())</code>
                           </td><td rowspan="1" colspan="1">כ״ו טבת תשס״ג</td></tr><tr><td rowspan="1" colspan="1">Julian (Old Style)</td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D] [MNn] [Y]", "en", "OS", ())</code>
                           </td><td rowspan="1" colspan="1">18 December 2002</td></tr><tr><td rowspan="1" colspan="1">Thai</td><td rowspan="1" colspan="1">
                              <code nobreak="false">format-date($d, "[D&amp;#x0E51;] [Mn] [Y&amp;#x0E51;]", "th", "BE", ())</code>
                           </td><td rowspan="1" colspan="1">๓๑ ธันวาคม 
๒๕๔๕</td></tr></tbody></table></div3></div2><div2 id="parsing-dates-and-times"><head>Parsing dates and times</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-ietf-date</code></td><td rowspan="1" colspan="1">Parses a string containing the date and time in IETF format, returning the corresponding
               <code nobreak="false">xs:dateTime</code> value.</td></tr></tbody></table><p>A function is provided to parse dates and times expressed using syntax that is commonly encountered
            in internet protocols.</p><div3 id="func-parse-ietf-date"><head>fn:parse-ietf-date</head><glist><gitem><label>Summary</label><def><p>Parses a string containing the date and time in IETF format, returning the corresponding
               <code nobreak="false">xs:dateTime</code> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-ietf-date" return-type="xs:dateTime?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function accepts a string matching the production <code nobreak="false">input</code> in the
            following grammar:</p><table role="scrap"><tbody><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">input</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">S? (dayname ","? S)? ((datespec S time) | asctime) S?</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">dayname</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">"Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun" | "Monday | "Tuesday"
                     | "Wednesday" | "Thursday" | "Friday" | "Saturday" | "Sunday"</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">datespec</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">daynum dsep monthname dsep year</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">asctime</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">monthname dsep daynum S time S year</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">dsep</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">S | (S? "-" S?)</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">daynum</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">digit digit?</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">year</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">digit digit (digit digit)?</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">digit</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">[0-9]</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">monthname</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">"Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | "Jul" | "Aug" | "Sep" |
                     "Oct" | "Nov" | "Dec"</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">time</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">hours ":" minutes (":" seconds)? (S? timezone)?</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">hours</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <phrase><code nobreak="false">digit digit?</code></phrase>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">minutes</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">digit digit</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">seconds</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">digit digit ("." digit+)?</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">timezone</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">tzname | tzoffset (S? "(" S? tzname S? ")")?</code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">tzname</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">"UT" | "UTC" | "GMT" | "EST" | "EDT" | "CST" | "CDT" | "MST" | "MDT" | "PST"
                     | "PDT" </code>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">tzoffset</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <phrase><code nobreak="false">("+"|"-") hours ":"? minutes?</code></phrase>
               </td></tr><tr><td rowspan="1" colspan="1">
                  <code nobreak="false">S</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">::=</code>
               </td><td rowspan="1" colspan="1">
                  <code nobreak="false">(x09 | x0A | x0D | x20)+</code>
               </td></tr></tbody></table><p>The input is case-insensitive: upper-case and lower-case distinctions in the above
            grammar show the conventional usage, but otherwise have no significance.</p><p>If the input is the empty sequence, the result is the empty sequence.</p><p>The <code nobreak="false">dayname</code>, if present, is ignored.</p><p>The <code nobreak="false">daynum</code>, <code nobreak="false">monthname</code>, and <code nobreak="false">year</code> supply the day,
            month, and year of the resulting <code nobreak="false">xs:dateTime</code> value. A two-digit year
               <rfc2119>must</rfc2119> have 1900 added to it. A year such as 0070 is to be treated
            as given; negative years are not permitted.</p><p>The <code nobreak="false">hours</code>, <code nobreak="false">minutes</code>, and <code nobreak="false">seconds</code> (including
            fractional seconds) values supply the corresponding components of the resulting
               <code nobreak="false">xs:dateTime</code> value; if the <code nobreak="false">seconds</code> value 
            <phrase>or the fractional seconds value</phrase> is absent then zero
            is assumed.</p><p>If both a <code nobreak="false">tzoffset</code> and a <code nobreak="false">tzname</code> are supplied then the
               <code nobreak="false">tzname</code> is ignored.</p><p>If a <code nobreak="false">tzoffset</code> is supplied then this defines the hours and minutes parts of the timezone offset:</p><ulist><item><p>If it contains a colon, this separates the hours part from the minutes part.</p></item><item><p>Otherwise, the grammar allows a sequence of from one to four digits. These are interpreted
            as <code nobreak="false">H</code>, <code nobreak="false">HH</code>, <code nobreak="false">HMM</code>, or <code nobreak="false">HHMM</code> respectively, where <code nobreak="false">H</code>
            or <code nobreak="false">HH</code> is the hours part, and <code nobreak="false">MM</code> (if present) is the minutes part.</p></item><item><p>If the minutes part is absent it defaults to <code nobreak="false">00</code>.</p></item></ulist><p>If a <code nobreak="false">tzname</code> is supplied with no <code nobreak="false">tzoffset</code> then it is translated
            to a timezone offset as follows:</p><table role="data"><thead><tr><th rowspan="1" colspan="1">tzname</th><th rowspan="1" colspan="1">Offset</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">UT, UTC, GMT</td><td rowspan="1" colspan="1">00:00</td></tr><tr><td rowspan="1" colspan="1">EST</td><td rowspan="1" colspan="1">-05:00</td></tr><tr><td rowspan="1" colspan="1">EDT</td><td rowspan="1" colspan="1">-04:00</td></tr><tr><td rowspan="1" colspan="1">CST</td><td rowspan="1" colspan="1">-06:00</td></tr><tr><td rowspan="1" colspan="1">CDT</td><td rowspan="1" colspan="1">-05:00</td></tr><tr><td rowspan="1" colspan="1">MST</td><td rowspan="1" colspan="1">-07:00</td></tr><tr><td rowspan="1" colspan="1">MDT</td><td rowspan="1" colspan="1">-06:00</td></tr><tr><td rowspan="1" colspan="1">PST</td><td rowspan="1" colspan="1">-08:00</td></tr><tr><td rowspan="1" colspan="1">PDT</td><td rowspan="1" colspan="1">-07:00</td></tr></tbody></table><p>If neither a <code nobreak="false">tzoffset</code> nor <code nobreak="false">tzname</code> is supplied, a timezone
            offset of <code nobreak="false">00:00</code> is assumed.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref spec="FO" class="RG" code="0010"/> if the input does
            not match the grammar, or if the resulting date/time value is invalid
            (for example, <code nobreak="false">"31 February"</code>).</p></def></gitem><gitem><label>Notes</label><def><note><p>The <code nobreak="false">parse-ietf-date</code> function attempts to interpret its input as a date
            in any of the three formats specified by HTTP <bibref ref="rfc2616"/>.</p><p>These formats are used widely on the Internet to represent timestamps, and were
            specified in:</p><ulist><item><p><bibref ref="rfc822"/> (electronic mail), extended in <bibref ref="rfc1123"/> to allow four-digit years;</p></item><item><p><bibref ref="rfc850"/> (Usenet Messages), obsoleted by <bibref ref="rfc1036"/>;</p></item><item><p>POSIX <code nobreak="false">asctime()</code> format</p></item></ulist><p><bibref ref="rfc2616"/> (HTTP) officially uses a subset of those three formats restricted to GMT.</p><p>The grammar for this function is slightly more liberal than the RFCs (reflecting the internet tradition of being liberal in what is accepted).
            For example the function:</p><olist><item><p>Accepts a single-digit value where appropriate in place of a two-digit value with a leading zero (so
                  <code nobreak="false">"Wed 1 Jun"</code> is acceptable in place of <code nobreak="false">"Wed 01 Jun"</code>,
                  <phrase>and the timezone offset <code nobreak="false">"-5:00"</code> is equivalent to <code nobreak="false">"-05:00"</code>)</phrase></p></item><item><p>Accepts one or more whitespace characters (x20, x09, x0A, x0D) wherever a single
                  space is required, and allows whitespace to be omitted where it is not required
                  for parsing</p></item><item><p>Accepts and ignores whitespace characters (x20, x09, x0A, x0D) at the start or end
                  of the string.</p></item></olist><p>In new protocols IETF recommends the format of <bibref ref="rfc3339"/>, which is based on a profile of
            ISO 8601 similar to that already used in XPath and XSD, but the “approximate” <bibref ref="rfc822"/>
            format described here is very widely used.</p><p>An <bibref ref="rfc1123"/> date can be generated approximately using <function>fn:format-dateTime</function> with a picture
            string of <code nobreak="false">"[FNn3], [D01] [MNn3] [Y04] [H01]:[m01]:[s01] [Z0000]"</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-ietf-date("Wed, 06 Jun 1994 07:29:35 GMT")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:dateTime("1994-06-06T07:29:35Z")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-ietf-date("Wed, 6 Jun 94 07:29:35 GMT")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:dateTime("1994-06-06T07:29:35Z")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-ietf-date("Wed Jun 06 11:54:45 EST 2013")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:dateTime("2013-06-06T11:54:45-05:00")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-ietf-date("Sunday, 06-Nov-94 08:49:37 GMT")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:dateTime("1994-11-06T08:49:37Z")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-ietf-date("Wed, 6 Jun 94 07:29:35 +0500")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:dateTime("1994-06-06T07:29:35+05:00")</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="QName-funcs"><head>Processing QNames and NOTATIONS</head><div2 id="QName-constructors"><head>Functions to create a QName</head><p>In XPath 4.0, statically-known QNames can be expressed using a QName literal such as
            <code nobreak="false">#xml:space</code>. Where the QName is not known statically, 
            the <code nobreak="false">xs:QName</code> constructor function can be used.</p><p>In addition to the <code nobreak="false">xs:QName</code> constructor function, QName values can
               be constructed by combining a namespace URI, prefix, and local name, or by resolving
               a lexical QName against the in-scope namespaces of an element node. This section
                    defines functions that perform these operations. 
					Leading and trailing whitespace, if present, is stripped from
                    string arguments before the result is constructed.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:QName</code></td><td rowspan="1" colspan="1">Returns an <code nobreak="false">xs:QName</code> value formed using a supplied namespace URI and lexical QName.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-QName</code></td><td rowspan="1" colspan="1">Returns an <code nobreak="false">xs:QName</code> value formed by parsing an EQName.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:resolve-QName</code></td><td rowspan="1" colspan="1">Returns an <code nobreak="false">xs:QName</code> value (that is, an expanded-QName) by taking an
               <code nobreak="false">xs:string</code> that has the lexical form of an <code nobreak="false">xs:QName</code> (a
            string in the form <code nobreak="false">"prefix:local-name"</code> or <code nobreak="false">"local-name"</code>)
            and resolving it using the in-scope namespaces for a given element.</td></tr></tbody></table><div3 id="func-QName"><head>fn:QName</head><glist><gitem><label>Summary</label><def><p>Returns an <code nobreak="false">xs:QName</code> value formed using a supplied namespace URI and lexical QName.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="QName" return-type="xs:QName" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="uri" type="xs:string?"/><arg name="qname" type="xs:string"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The namespace URI in the returned QName is taken from <code nobreak="false">$uri</code>. If
               <code nobreak="false">$uri</code> is the zero-length string or the empty sequence, it represents
            “no namespace”.</p><p>The prefix (or absence of a prefix) in <code nobreak="false">$qname</code> is retained in the
            returned <code nobreak="false">xs:QName</code> value.</p><p>The local name in the result is taken from the local part of
            <code nobreak="false">$qname</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="CA" code="0002"/> if <code nobreak="false">$qname</code>
            does not have the correct lexical form for an instance of <code nobreak="false">xs:QName</code>.</p><p>A dynamic error is raised <errorref class="CA" code="0002"/> if <code nobreak="false">$uri</code>
            is the zero-length string or the empty sequence, and the value of
               <code nobreak="false">$qname</code> contains a colon (<code nobreak="false">:</code>).</p><p>A dynamic error <rfc2119>may</rfc2119> be raised <errorref class="CA" code="0002"/> if
               <code nobreak="false">$uri</code> is not a valid URI (XML Namespaces 1.0) or IRI (XML Namespaces
            1.1). </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">QName("http://www.example.com/example", "person")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#Q{http://www.example.com/example}person</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">QName("http://www.example.com/example", "ht:person")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#Q{http://www.example.com/example}ht:person</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-parse-QName" diff="add" at="B"><head>fn:parse-QName</head><changes><change issue="1" PR="207" date="2022-11-15">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns an <code nobreak="false">xs:QName</code> value formed by parsing an EQName.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-QName" return-type="xs:QName?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		namespaces.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the result is the empty sequence.</p><p>Otherwise, leading and trailing whitespace in <code nobreak="false">$value</code> is stripped:
            call the result <var>V</var></p><p>If <var>V</var> is castable to <code nobreak="false">xs:NCName</code>,
               the result is <code nobreak="false">fn:QName("", $value)</code>: that is, a QName in no namespace.</p><p>If <var>V</var> is in the lexical space of <code nobreak="false">xs:QName</code>
               (that is, if it is in the form <code nobreak="false">prefix:local</code>), the result is <code nobreak="false">xs:QName($value)</code>.
               Note that this result depends on the in-scope prefixes in the static context, and may result in
               various error conditions.</p><p>If <var>V</var> takes the form of a
               XPath <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XP40" ref="URIQualifiedName" xlink:type="simple">URIQualifiedName</xnt>
               (that is, <code nobreak="false">Q{uri}local</code>, where the <code nobreak="false">uri</code> part may be zero-length,
               or <code nobreak="false">Q{uri}prefix:local</code>),
               then the result is <code nobreak="false">fn:QName(uri, local)</code> or <code nobreak="false">fn:QName(uri, prefix:local)</code>
               respectively.</p><p>The rules used for parsing a <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XP40" ref="BracedURILiteral" xlink:type="simple"/> within a 
            <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XP40" ref="URIQualifiedName" xlink:type="simple">URIQualifiedName</xnt> are the XPath rules,
                  not the XQuery rules (the XQuery rules require special characters such as <code nobreak="false">&lt;</code>
                  and <code nobreak="false">&amp;</code> to be escaped).</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="CA" code="0002"/>
               if the supplied value of <code nobreak="false">$value</code>, after whitespace normalization,
               does not match the XPath production <xspecref spec="XP40" ref="EQName">EQName</xspecref>,
               or if the input is a <code nobreak="false">URIQualifiedName</code> in which the namespace prefix
               is present but the namespace URI is absent.</p><p>A dynamic error is raised <errorref class="NS" code="0004"/> if
               the supplied value of <code nobreak="false">$value</code>, after whitespace normalization,
               is in the form <code nobreak="false">prefix:local</code> (with a non-absent prefix), and
               the prefix cannot be resolved to a namespace URI using the in-scope namespace
               bindings from the static context.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:parse-QName("Q{http://www.example.com/ns}person")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:QName("http://www.example.com/ns", "person")</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:parse-QName("person")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:QName("", "person")</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:parse-QName("Q{}person")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:QName("", "person")</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:parse-QName("Q{http://www.example.com/ns}xmp:person")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">fn:QName("http://www.example.com/ns", "xmp:person")</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">declare namespace xmp = "http://www.example.com/ns";
fn:parse-QName("xmp:person")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">#Q{http://www.example.com/ns}xmp:person</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-resolve-QName"><head>fn:resolve-QName</head><glist><gitem><label>Summary</label><def><p>Returns an <code nobreak="false">xs:QName</code> value (that is, an expanded-QName) by taking an
               <code nobreak="false">xs:string</code> that has the lexical form of an <code nobreak="false">xs:QName</code> (a
            string in the form <code nobreak="false">"prefix:local-name"</code> or <code nobreak="false">"local-name"</code>)
            and resolving it using the in-scope namespaces for a given element.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="resolve-QName" return-type="xs:QName?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="element" type="element()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, returns the empty sequence.</p><p>More specifically, the function searches the namespace bindings of <code nobreak="false">$element</code>
            for a binding whose name matches the prefix of <code nobreak="false">$value</code>, or the zero-length
            string if it has no prefix, and returns an expanded-QName whose local name is taken
            from the supplied <code nobreak="false">$value</code>, and whose namespace URI is taken from the string
            value of the namespace binding.</p><p>If the <code nobreak="false">$value</code> has no prefix, and there is no namespace binding for
               <code nobreak="false">$element</code> corresponding to the default (unnamed) namespace, then the
            resulting expanded-QName has no namespace part.</p><p>The prefix (or absence of a prefix) in the supplied <code nobreak="false">$value</code> argument is
            retained in the returned expanded-QName, as described in <xspecref spec="DM40" ref="terminology"/>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="CA" code="0002"/> if <code nobreak="false">$value</code> does
            not have the correct lexical form for an instance of <code nobreak="false">xs:QName</code>.</p><p>A dynamic error is raised <errorref class="NS" code="0004"/> if <code nobreak="false">$value</code> has
            a prefix and there is no namespace binding for <code nobreak="false">$element</code> that matches this
            prefix.</p></def></gitem><gitem><label>Notes</label><def><note><p>Sometimes the requirement is to construct an <code nobreak="false">xs:QName</code> without using the
            default namespace. This can be achieved by writing:</p><eg xml:space="preserve">if (contains($value, ":"))
then resolve-QName($value, $element)
else QName("", $value)</eg><p>If the requirement is to construct an <code nobreak="false">xs:QName</code> using the namespaces in the
            static context, then the <code nobreak="false">xs:QName</code> constructor should be used.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $element := &lt;e xmlns:eg="http://ns.example.com/"/&gt;</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">fn:resolve-QName("hello", $element)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#Q{}hello</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">fn:resolve-QName("eg:myFunc", $element)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#Q{http://ns.example.com/}eg:myFunc</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="QName-functions"><head>Functions and operators on QNames</head><p>This section specifies functions on QNames as defined in <bibref ref="xmlschema-2"/>.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:prefix-from-QName</code></td><td rowspan="1" colspan="1">Returns the prefix component of the supplied QName.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:local-name-from-QName</code></td><td rowspan="1" colspan="1">Returns the local part of the supplied QName.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:namespace-uri-from-QName</code></td><td rowspan="1" colspan="1">Returns the namespace URI part of the supplied QName.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:expanded-QName</code></td><td rowspan="1" colspan="1">Returns a string representation of an <code nobreak="false">xs:QName</code> in the format <code nobreak="false">Q{uri}local</code>.</td></tr></tbody></table><div3 id="func-prefix-from-QName"><head>fn:prefix-from-QName</head><glist><gitem><label>Summary</label><def><p>Returns the prefix component of the supplied QName.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="prefix-from-QName" return-type="xs:NCName?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:QName?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>If <code nobreak="false">$value</code> has no prefix component the function returns the empty
            sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:NCName</code> representing the prefix
            component of <code nobreak="false">$value</code>.</p></def></gitem></glist></div3><div3 id="func-local-name-from-QName"><head>fn:local-name-from-QName</head><glist><gitem><label>Summary</label><def><p>Returns the local part of the supplied QName.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="local-name-from-QName" return-type="xs:NCName?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:QName?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:NCName</code> representing the local part of
            <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">local-name-from-QName(#Q{http://www.example.com/ns}person)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"person"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-namespace-uri-from-QName"><head>fn:namespace-uri-from-QName</head><glist><gitem><label>Summary</label><def><p>Returns the namespace URI part of the supplied QName.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="namespace-uri-from-QName" return-type="xs:anyURI?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:QName?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns an <code nobreak="false">xs:anyURI</code> representing the namespace URI
            part of <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> is in no namespace, the function returns the zero-length
               <code nobreak="false">xs:anyURI</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">namespace-uri-from-QName(#Q{http://www.example.com/ns}person)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">xs:anyURI("http://www.example.com/ns")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-expanded-QName" diff="add" at="B"><head>fn:expanded-QName</head><changes><change issue="1" PR="207" date="2022-11-15">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a string representation of an <code nobreak="false">xs:QName</code> in the format <code nobreak="false">Q{uri}local</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="expanded-QName" return-type="xs:string?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:QName?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, returns the empty sequence.</p><p>The result is a string in the format <code nobreak="false">Q{uri}local</code>, where:</p><ulist><item><p><code nobreak="false">uri</code> 
               is the result of <code nobreak="false">fn:string(fn:namespace-uri-from-QName($value))</code>
               (which will be a zero-length string if the QName is in no namespace), and </p></item><item><p><code nobreak="false">local</code> is the result of 
               <code nobreak="false">fn:local-name-from-QName($value)</code>.</p></item></ulist><p>There is no escaping of special characters in the namespace URI. If the namespace URI
            contains curly braces, the resulting string will not be a valid 
            <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XP40" ref="BracedURILiteral" xlink:type="simple">BracedURILiteral</xnt>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">QName("http://example.com/", "person")
=&gt; expanded-QName()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Q{http://example.com/}person"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">QName("", "person")
=&gt; expanded-QName()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Q{}person"</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="NOTATION-functions"><head>Processing NOTATIONs</head><p>There are no functions designed explicitly to process <code nobreak="false">xs:NOTATION</code> items.</p><p>However, some generic functions such as <function>fn:atomic-equal</function> and 
            <code nobreak="false">fn:compare</code> can be used on <code nobreak="false">xs:NOTATION</code> items.</p></div2></div1><div1 id="binary-functions"><head>Processing binary values</head><p>Binary data is represented using the data types <code nobreak="false">xs:hexBinary</code> and
         <code nobreak="false">xs:base64Binary</code>. Both types have the same value space: a sequence of octets,
         which can be considered as integers in the range 0 to 255.</p><p>The coercion rules of XPath 4.0 ensure that the two types are interoperable; a function
         that declares an argument of type <code nobreak="false">xs:hexBinary</code> will always accept a value of
         type <code nobreak="false">xs:base64Binary</code>, and vice versa.</p><p>There are no functions defined in this document provided exclusively for processing
         binary data. A number of generic functions are available:</p><ulist><item><p>Functions such as <function>fn:atomic-equal</function>, <code nobreak="false">fn:deep-equal</code>, and
               <function>fn:index-of</function> compare binary values for equality.</p></item><item><p>Functions such as <function>fn:compare</function>, <function>fn:sort-by</function>,
               and <function>fn:max</function> compare binary values for ordering.</p></item><item><p>The function <function>fn:string</function> creates a string representation of a binary value.</p></item><item><p>The constructor functions <code nobreak="false">xs:string</code>, <code nobreak="false">xs:hexBinary</code>,
            and <code nobreak="false">xs:base64Binary</code> can be used to convert binary values to and from their
            string representation.</p></item></ulist><p>The function <function>fn:unparsed-binary</function> reads an external resource and returns
         is content as an <code nobreak="false">xs:base64Binary</code> value.</p><p>A library of functions specific to processing of binary data can be found in <bibref ref="binary-40"/>.</p></div1><div1 id="node-functions"><head>Processing nodes</head><div2 id="accessors"><head>Accessors</head><p>Accessors and their semantics are described in <bibref ref="xpath-datamodel-40"/>. Some of
                   these accessors are exposed to the user through the functions described below.</p><p>Each of these functions has an arity-zero signature which is equivalent to the arity-one
            form, with the context value supplied as the implicit first argument. In addition, each of the
            arity-one functions accepts the empty sequence as the argument, in which case it generally delivers
            the empty sequence as the result: the exception is <function>fn:string</function>, which delivers
            a zero-length string.</p><table role="data"><col width="25%" span="1"/><col width="25%" span="1"/><col width="25%" span="1"/><col width="25%" span="1"/><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Accessor</th><th rowspan="1" colspan="1">Accepts</th><th rowspan="1" colspan="1">Returns</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">
                               <function>fn:node-name</function>
                           </td><td rowspan="1" colspan="1">
                               <code nobreak="false">node-name</code>
                           </td><td rowspan="1" colspan="1">node (optional)</td><td rowspan="1" colspan="1"><code nobreak="false">xs:QName</code> (optional)
                           </td></tr><tr><td rowspan="1" colspan="1">
                               <function>fn:nilled</function>
                           </td><td rowspan="1" colspan="1">
                               <code nobreak="false">nilled</code>
                           </td><td rowspan="1" colspan="1">node (optional)</td><td rowspan="1" colspan="1"><code nobreak="false">xs:boolean</code> (optional)
                           </td></tr><tr><td rowspan="1" colspan="1">
                               <function>fn:string</function>
                           </td><td rowspan="1" colspan="1">
                               <code nobreak="false">string-value</code>
                           </td><td rowspan="1" colspan="1">item (optional)</td><td rowspan="1" colspan="1">
                               <code nobreak="false">xs:string</code>
                           </td></tr><tr><td rowspan="1" colspan="1">
                               <function>fn:data</function>
                           </td><td rowspan="1" colspan="1">
                               <code nobreak="false">typed-value</code>
                           </td><td rowspan="1" colspan="1">zero or more items</td><td rowspan="1" colspan="1">a sequence of atomic items</td></tr><tr><td rowspan="1" colspan="1">
                               <function>fn:base-uri</function>
                           </td><td rowspan="1" colspan="1">
                               <code nobreak="false">base-uri</code>
                           </td><td rowspan="1" colspan="1">node (optional)</td><td rowspan="1" colspan="1"><code nobreak="false">xs:anyURI</code> (optional)
                           </td></tr><tr><td rowspan="1" colspan="1">
                               <function>fn:document-uri</function>
                           </td><td rowspan="1" colspan="1">
                               <code nobreak="false">document-uri</code>
                           </td><td rowspan="1" colspan="1">node (optional)</td><td rowspan="1" colspan="1"><code nobreak="false">xs:anyURI</code> (optional)
                           </td></tr></tbody></table><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:base-uri</code></td><td rowspan="1" colspan="1">Returns the base URI of a node.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:document-uri</code></td><td rowspan="1" colspan="1">Returns the URI of a resource where a document can be found, if available.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:nilled</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> for an element that is <term>nilled</term>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:node-name</code></td><td rowspan="1" colspan="1">Returns the name of a node, as an <code nobreak="false">xs:QName</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:string</code></td><td rowspan="1" colspan="1">Returns the value of <code nobreak="false">$value</code> represented as an <code nobreak="false">xs:string</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:data</code></td><td rowspan="1" colspan="1">Returns the result of atomizing a sequence. This process flattens arrays, and replaces
            nodes by their typed values.</td></tr></tbody></table><div3 id="func-base-uri"><head>fn:base-uri</head><changes><change issue="2148" PR="2223" date="2025-10-02">An error may now be raised if the base URI is not a valid LEIRI reference.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the base URI of a node.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="base-uri" return-type="xs:anyURI?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, the function returns the empty
            sequence.</p><p>Otherwise, the function returns the value of the <code nobreak="false">dm:base-uri</code> accessor
            applied to the node <code nobreak="false">$node</code>. This accessor is defined, for each kind of
            node, in the XDM specification (See <xspecref spec="DM40" ref="dm-base-uri"/>).</p><note><p>As explained in XDM, document, element and processing-instruction nodes have a
            base-uri property which may be empty. The base-uri property for all other node kinds is
            the empty sequence. The dm:base-uri accessor returns the base-uri property of a node if
            it exists and is non-empty; otherwise it returns the result of applying the dm:base-uri
            accessor to its parent, recursively. If the node does not have a parent, or if the
            recursive ascent up the ancestor chain encounters a parentless node whose base-uri
            property is empty, the empty sequence is returned. In the case of namespace nodes,
            however, the result is always the empty sequence — it does not depend on the base URI of
            the parent element.</p></note><p>See also <function>fn:static-base-uri</function>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">node()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist><p>A dynamic error <rfc2119>may</rfc2119> be raised <errorref class="RG" code="0002"/>
            if the base URI is not a valid Legacy Extended IRI reference (see <bibref ref="LEIRI"/>). </p></def></gitem></glist></div3><div3 id="func-document-uri"><head>fn:document-uri</head><changes><change issue="898 1161" PR="1265" date="2024-07-02">The constraints on the result of the function have been relaxed.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the URI of a resource where a document can be found, if available.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="document-uri" return-type="xs:anyURI?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, the function returns the empty sequence.</p><p>If <code nobreak="false">$node</code> is not a document node, the function returns the empty
            sequence.</p><p>Otherwise, the function returns the value of the <code nobreak="false">document-uri</code> accessor
            applied to <code nobreak="false">$node</code>, as defined in <bibref ref="xpath-datamodel-31"/> (See
               <xspecref spec="DM40" ref="DocumentNodeAccessors"/>).</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">node()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>In the 3.1 version of this specification, it was mandated that two distinct documents could
         not have the same document-uri property: more specifically, it was guaranteed that for any document node
         <code nobreak="false">$D</code>, either <code nobreak="false">document-uri($D)</code> would be absent, or <code nobreak="false">doc(document-uri($D))</code>
         would return <code nobreak="false">$D</code>.</p><p>For various reasons, this constraint has proved impractical. Different parts of an application
            may read the same external resource in different ways, for example with or without validation or
            whitespace stripping, leading to different document nodes derived from the same external
            resource having the same <code nobreak="false">document-uri</code> property. In addition, the specification
            explicitly allows implementations, at user request, to relax the requirements for determinism 
            of resource access functions, which makes it possible for multiple calls of functions such as
            <function>fn:doc</function>, <function>fn:json-doc</function>, or <function>fn:collection</function> to return
            different results for the same supplied URI.</p><p>Although the uniqueness of the <code nobreak="false">document-uri</code> property is no longer
            an absolute constraint, it is still desirable that implementations should where possible
            respect the principle that URIs are usable as identifiers for resources.</p><p diff="chg" at="issue898">In the case of a document node <code nobreak="false">$D</code> returned by the <function>fn:doc</function>
            function, it will generally be the case that <code nobreak="false">fn:document-uri($D)</code> returns a URI <code nobreak="false">$U</code>
            such that a call on <code nobreak="false">fn:doc($U)</code> in the same dynamic context will return the same document
            node <code nobreak="false">$D</code>. The URI <code nobreak="false">$U</code> will not necessarily be the same URI that was originally
            passed to the <function>fn:doc</function> function, since several URIs may identify the same resource.</p><p diff="chg" at="issue898">It is <rfc2119>recommended</rfc2119> that implementations of <function>fn:collection</function>
            should ensure that any documents included in the returned collection, if they have a non-empty
            <function>fn:document-uri</function> property, should be such that a call on <function>fn:doc</function> supplying this URI
            returns the same document node.</p></note></def></gitem></glist></div3><div3 id="func-nilled"><head>fn:nilled</head><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> for an element that is <term>nilled</term>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="nilled" return-type="xs:boolean?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise the function returns the result of the <code nobreak="false">dm:nilled</code> accessor as
            defined in <bibref ref="xpath-datamodel-31"/> (see <xspecref spec="DM40" ref="dm-nilled"/>).</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">node()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$node</code> is not an element node, the function returns the empty
            sequence.</p><p>If <code nobreak="false">$node</code> is an untyped element node, the function returns <code nobreak="false">false</code>.</p><p>In practice, the function returns <code nobreak="false">true</code> only for an element node that has
            the attribute <code nobreak="false">xsi:nil="true"</code> and that is successfully validated against a
            schema that defines the element to be nillable; the detailed rules, however, are defined
            in <bibref ref="xpath-datamodel-31"/>.</p></note></def></gitem></glist></div3><div3 id="func-node-name"><head>fn:node-name</head><glist><gitem><label>Summary</label><def><p>Returns the name of a node, as an <code nobreak="false">xs:QName</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="node-name" return-type="xs:QName?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, the empty sequence is returned.</p><p>Otherwise, the function returns the result of the <code nobreak="false">dm:node-name</code> accessor as
            defined in <bibref ref="xpath-datamodel-31"/> (see <xspecref spec="DM40" ref="dm-node-name"/>).</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/>.</p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">node()?</code>, 
                  type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>For element and attribute nodes, the name of the node is returned as an
               <code nobreak="false">xs:QName</code>, retaining the prefix, namespace URI, and local part.</p><p>For processing instructions, the name of the node is returned as an
               <code nobreak="false">xs:QName</code> in which the prefix and namespace URI are <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p><p>For a namespace node, the function returns the empty sequence if the node represents the
            default namespace; otherwise it returns an <code nobreak="false">xs:QName</code> in which prefix and
            namespace URI are <xtermref ref="dt-absent" spec="DM40">absent</xtermref> and the local
            part is the namespace prefix being bound.</p><p>For all other kinds of node, the function returns the empty sequence.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;doc&gt;
  &lt;p id="alpha" xml:id="beta"&gt;One&lt;/p&gt;
  &lt;p id="gamma" xmlns="http://example.com/ns"&gt;Two&lt;/p&gt;
  &lt;ex:p id="delta" xmlns:ex="http://example.com/ns"&gt;Three&lt;/ex:p&gt;
  &lt;?pi 3.14159?&gt;
&lt;/doc&gt;
         </eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">node-name($e//*[@id = 'alpha'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">QName("", "p")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">node-name($e//*[@id = 'gamma'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">QName("http://example.com/ns", "p")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">node-name($e//*[@id = 'delta'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">QName("http://example.com/ns", "ex:p")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">node-name($e//processing-instruction())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">QName("", "pi")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">node-name($e//*[@id = 'alpha']/text())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">node-name($e//*[@id = 'alpha']/@id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">QName("", "id")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">node-name($e//*[@id = 'alpha']/@xml:id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#xml:id</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-string"><head>fn:string</head><glist><gitem><label>Summary</label><def><p>Returns the value of <code nobreak="false">$value</code> represented as an <code nobreak="false">xs:string</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="string" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="item()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the zero-length
            string.</p><p>If <code nobreak="false">$value</code> is an <xtermref spec="DM40" ref="dt-XNode"/>, 
            the function returns the string value of the node, as obtained using the
                     <code nobreak="false">dm:string-value</code> accessor defined in <bibref ref="xpath-datamodel-31"/> (see <xspecref spec="DM40" ref="dm-string-value"/>).</p><p>If <code nobreak="false">$value</code> is a <xtermref spec="DM40" ref="dt-JNode"/>, 
            the function returns the result of <code nobreak="false">string(jvalue($value))</code>.
         This will fail in the case where <code nobreak="false">jvalue($value)</code> is a map or an array.</p><p>If <code nobreak="false">$value</code> is an atomic item, the function returns the result of the expression <code nobreak="false">$value cast
                     as xs:string</code> (see <specref ref="casting"/>).</p><p>In all other cases, a dynamic error occurs (see below).</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$value</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="dynamic"/>.</p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">item()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist><p>A type error is raised <errorref class="TY" code="0014" type="type"/> if
               <code nobreak="false">$value</code> is a function item (this includes maps and arrays).</p></def></gitem><gitem><label>Notes</label><def><note><p>Every node has a string value, even an element with element-only
            content (which has no typed value). Moreover, casting an atomic item to a string always
            succeeds. Functions, maps, and arrays have no string value, so these 
            satisfy the type signature but cause failure. Applying the <function>string</function>
            function to a JNode succeeds if the JNode wraps a simple value such as a string, number,
         or boolean, or if it wraps an XNode, but it fails in the case where the JNode wraps a map
         or an array.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $para := &lt;para&gt;There lived a &lt;term author="Tolkien"&gt;hobbit&lt;/term&gt;.&lt;/para&gt;
         </eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string(23)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"23"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string(false())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"false"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string("Paris")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Paris"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string((1, 2, 3))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error XPTY0004.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string([ [ 1, 2 ], [ 3, 4 ] ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FOTY0014.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string(abs#1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FOTY0014.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string({ "x": [10, 20, 30] }/x/*[3])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"30"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">string($para)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"There lived a hobbit."</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-data"><head>fn:data</head><glist><gitem><label>Summary</label><def><p>Returns the result of atomizing a sequence. This process flattens arrays, and replaces
            nodes by their typed values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="data" return-type="xs:anyAtomicType*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p> The result of <function>fn:data</function> is the sequence of atomic items produced by
            applying the following rules to each item in <code nobreak="false">$input</code>:</p><ulist><item><p>If the item is an atomic item, it is appended to the result sequence.</p></item><item><p>If the item is an <xtermref spec="DM40" ref="dt-XNode"/>, 
                  the typed value of the node is appended to the result
                  sequence. The typed value is a sequence of zero or more atomic items:
                  specifically, the result of the <code nobreak="false">dm:typed-value</code> accessor as defined in
                     <bibref ref="xpath-datamodel-31"/> (See <xspecref spec="DM40" ref="dm-typed-value"/>).</p></item><item><p>If the item is a <xtermref spec="DM40" ref="dt-JNode"/>,
               the atomized value of its <term>·jvalue·</term> property is appended to
               the result sequence.</p></item><item><p>If the item is an array, the result of applying <function>fn:data</function> to
                  each member of the array, in order, is appended to the result sequence.</p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <errorref class="TY" code="0012" type="type"/> if an item in the
            sequence <code nobreak="false">$input</code> is a node that does not have a typed value. </p><p>A type error is raised <errorref class="TY" code="0013" type="dynamic"/> if an item in
            the sequence <code nobreak="false">$input</code> is a function item other than
               an array. </p><p>A type error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/>
            if <code nobreak="false">$input</code> is omitted and the context value is
               <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The process of applying the <function>fn:data</function> function to a sequence is referred to
            as <term>atomization</term>. In many cases an explicit call on <function>fn:data</function> is
            not required, because atomization is invoked implicitly when a node or sequence of nodes
            is supplied in a context where an atomic item or sequence of atomic items is
            required.</p><p>The result of atomizing the empty sequence is the empty sequence.</p><p>The result of atomizing the empty array is the empty sequence.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $para := &lt;para&gt;There lived a &lt;term author="Tolkien"&gt;hobbit&lt;/term&gt;.&lt;/para&gt;
         </eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">data(123)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">123</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">data((123, 456))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">123, 456</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">data([ [ 1, 2 ], [ 3, 4 ] ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2, 3, 4</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">data($para)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:untypedAtomic("There lived a hobbit.")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">data($para/term/@author)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">xs:untypedAtomic("Tolkien")</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">data(abs#1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FOTY0013.</p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="other-node-functions"><head>Other properties of nodes</head><p>This section specifies further functions that return properties of nodes. 
               Nodes are formally defined in <xspecref spec="DM31" ref="Node"/>.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:has-children</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the supplied GNode has one or more child nodes (of any kind).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:in-scope-namespaces</code></td><td rowspan="1" colspan="1">Returns the in-scope namespaces of an element node, as a map.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:in-scope-prefixes</code></td><td rowspan="1" colspan="1">Returns the prefixes of the in-scope namespaces for an element node.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:lang</code></td><td rowspan="1" colspan="1">This function tests whether the language of <code nobreak="false">$node</code>, or the context value if
            the second argument is omitted, as specified by <code nobreak="false">xml:lang</code> attributes is the
            same as, or is a sublanguage of, the language specified by <code nobreak="false">$language</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:local-name</code></td><td rowspan="1" colspan="1">Returns the local part of the name of <code nobreak="false">$node</code> as an <code nobreak="false">xs:string</code>
            that is either the zero-length string, or has the lexical form of an
               <code nobreak="false">xs:NCName</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:name</code></td><td rowspan="1" colspan="1">Returns the name of a node, as an <code nobreak="false">xs:string</code> that is either the zero-length
            string, or has the lexical form of an <code nobreak="false">xs:QName</code>. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:namespace-uri</code></td><td rowspan="1" colspan="1">Returns the namespace URI part of the name of <code nobreak="false">$node</code>, as an
               <code nobreak="false">xs:anyURI</code> value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:namespace-uri-for-prefix</code></td><td rowspan="1" colspan="1">Returns the namespace URI of one of the in-scope namespaces for <code nobreak="false">$element</code>,
            identified by its namespace prefix.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:path</code></td><td rowspan="1" colspan="1">Returns a path expression that can be used to select the supplied node relative to the
            root of its containing document.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:root</code></td><td rowspan="1" colspan="1">Returns the root of the tree to which <code nobreak="false">$node</code> belongs. The
         function can be applied both to <xtermref spec="DM40" ref="dt-XNode">XNodes</xtermref>
         and to <xtermref spec="DM40" ref="dt-JNode">JNodes</xtermref>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:siblings</code></td><td rowspan="1" colspan="1">Returns the supplied GNode together with its siblings, in document order.</td></tr></tbody></table><div3 id="func-has-children"><head>fn:has-children</head><changes><change issue="2100" PR="2149" date="2025-08-12">Generalized to work with JNodes as well as XNodes.</change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the supplied GNode has one or more child nodes (of any kind).</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="has-children" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="gnode()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Provided that the supplied argument <code nobreak="false">$node</code> matches the expected type
               <code nobreak="false">gnode()?</code>, the result of the function call
               <code nobreak="false">fn:has-children($node)</code> is defined to be the same as the result of the
            expression <code nobreak="false">fn:exists($node/child::gnode())</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">gnode()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$node</code> is the empty sequence, the result is <code nobreak="false">false</code>.</p><p>The motivation for this function is to support streamed evaluation. According to the
            streaming rules in <bibref ref="xslt-40"/>, the following construct is not
            streamable:</p><eg xml:space="preserve">
&lt;xsl:if test="exists(row)"&gt;
  &lt;ulist&gt;
    &lt;xsl:for-each select="row"&gt;
      &lt;item&gt;&lt;xsl:value-of select="."/&gt;&lt;/item&gt;
    &lt;/xsl:for-each&gt;
  &lt;/ulist&gt;
&lt;/xsl:if&gt;  
</eg><p>This is because it makes two downward selections to read the child <code nobreak="false">row</code>
            elements. The use of <function>fn:has-children</function> in the <code nobreak="false">xsl:if</code> conditional
            is intended to circumvent this restriction.</p><p>Although the function was introduced to support streaming use cases, it has general
            utility as a convenience function.</p><p>If the supplied argument is a map or an array, it will automatically be coerced to a JNode.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;doc&gt;
  &lt;p id="alpha"&gt;One&lt;/p&gt;
  &lt;p/&gt;
  &lt;p&gt;Three&lt;/p&gt;
  &lt;?pi 3.14159?&gt;
&lt;/doc&gt;
         </eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">has-children($e)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">has-children($e//p[1])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">has-children($e//p[2])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">has-children($e//p[3])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">has-children($e//processing-instruction())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">has-children($e//p[1]/text())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">has-children($e//p[1]/@id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">jtree([1,2,3]) =&gt; has-children()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">jtree([]) =&gt; has-children()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-in-scope-namespaces" diff="add" at="A"><head>fn:in-scope-namespaces</head><changes><change date="2022-09-20">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the in-scope namespaces of an element node, as a map.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="in-scope-namespaces" return-type="map((xs:NCName | enum('')), xs:anyURI)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="element" type="element()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a map representing the prefixes of the in-scope
            namespaces for <code nobreak="false">$element</code>. The map contains one entry
         for each in-scope namespace: the key of the entry is the namespace
         prefix or a zero-length string, and the corresponding value is the namespace URI.</p><p>For namespace bindings that have a prefix, the key represents the prefix as an
            instance of <code nobreak="false">xs:NCName</code>. For the default namespace, which has no prefix, the key is
            the zero-length string as an instance of <code nobreak="false">xs:string</code>.</p><p>The order of entries in the returned map is <termref def="implementation-dependent"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The XML namespace is in scope for every element, so the result will always include an entry
            with key <code nobreak="false">"xml"</code> and corresponding value <code nobreak="false">http://www.w3.org/XML/1998/namespace</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := 
&lt;z:a xmlns="http://example.org/one" xmlns:z="http://example.org/two"&gt;
  &lt;b xmlns=""/&gt;
&lt;/z:a&gt;</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">in-scope-namespaces($e)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "": "http://example.org/one",
  "z": "http://example.org/two",
  "xml": "http://www.w3.org/XML/1998/namespace"
}</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-in-scope-prefixes"><head>fn:in-scope-prefixes</head><glist><gitem><label>Summary</label><def><p>Returns the prefixes of the in-scope namespaces for an element node.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="in-scope-prefixes" return-type="xs:string*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="element" type="element()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic-wrt-ordering">nondeterministic-wrt-ordering</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p diff="chg" at="A">The function returns the result of the expression
            <code nobreak="false">map:keys(fn:in-scope-namespaces($element))</code> (but in no defined order).</p></def></gitem><gitem><label>Notes</label><def><note><p>The XML namespace is in scope for every element, so the result will always include the string <code nobreak="false">"xml"</code>.</p></note></def></gitem></glist></div3><div3 id="func-lang"><head>fn:lang</head><glist><gitem><label>Summary</label><def><p>This function tests whether the language of <code nobreak="false">$node</code>, or the context value if
            the second argument is omitted, as specified by <code nobreak="false">xml:lang</code> attributes is the
            same as, or is a sublanguage of, the language specified by <code nobreak="false">$language</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="lang" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="language" type="xs:string?"/><arg name="node" type="node()" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The language of the argument <code nobreak="false">$node</code> is determined by the value of the
            <code nobreak="false">xml:lang</code> attribute on the node, or, if the node has no such attribute,
            by the value of the
               <code nobreak="false">xml:lang</code> attribute on the nearest ancestor of the node that has an
               <code nobreak="false">xml:lang</code> attribute. If there is no such ancestor, then the function
            returns <code nobreak="false">false</code>. </p><p>If <code nobreak="false">$language</code> is the empty sequence, it is interpreted as the zero-length
            string.</p><p>The relevant <code nobreak="false">xml:lang</code> attribute is determined by the value of the XPath
            expression:</p><eg xml:space="preserve">(ancestor-or-self::*/@xml:lang)[last()]</eg><p>If this expression returns the empty sequence, the function returns <code nobreak="false">false</code>. </p><p>Otherwise, the function returns <code nobreak="false">true</code> if and only if, based on a caseless
            default match as specified in section 3.13 of <bibref ref="Unicode"/>, either:</p><olist><item><p>
                  <code nobreak="false">$language</code> is equal to the string-value of the relevant
                     <code nobreak="false">xml:lang</code> attribute, or</p></item><item><p>
                  <code nobreak="false">$language</code> is equal to some substring of the string-value of the
                  relevant <code nobreak="false">xml:lang</code> attribute that starts at the start of the
                  string-value and ends immediately before a hyphen, <code nobreak="false">-</code>
                  (HYPHEN-MINUS, <code nobreak="false">#x002D</code>).</p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not a single node, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">&lt;para xml:lang="en"/&gt; -&gt; fn:lang("en")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">&lt;div xml:lang="en"&gt;&lt;para&gt;And now, and
                        forever!&lt;/para&gt;&lt;/div&gt; -&gt; fn:lang("en")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">&lt;para xml:lang="EN"/&gt; -&gt; fn:lang("en")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">&lt;para xml:lang="en-us"/&gt; -&gt; fn:lang("en")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">&lt;para xml:lang="EN"/&gt; -&gt; fn:lang("fr")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">&lt;para xml:lang="en-us"/&gt; -&gt; fn:lang("en-GB")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-local-name"><head>fn:local-name</head><glist><gitem><label>Summary</label><def><p>Returns the local part of the name of <code nobreak="false">$node</code> as an <code nobreak="false">xs:string</code>
            that is either the zero-length string, or has the lexical form of an
               <code nobreak="false">xs:NCName</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="local-name" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, the function returns the zero-length string.</p><p>If the node identified by <code nobreak="false">$node</code> has no name (that is, if it is a document
            node, a comment, a text node, or a namespace node having no name), the function returns
            the zero-length string.</p><p>Otherwise, the function returns the local part of the expanded-QName of the node
            identified by <code nobreak="false">$node</code>, as determined by the <code nobreak="false">dm:node-name</code> accessor
            defined in <xspecref spec="DM40" ref="dm-node-name"/>. This will be an
               <code nobreak="false">xs:string</code> whose lexical form is an <code nobreak="false">xs:NCName</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not a single node, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;doc&gt;
  &lt;p id="alpha" xml:id="beta"&gt;One&lt;/p&gt;
  &lt;p id="gamma" xmlns="http://example.com/ns"&gt;Two&lt;/p&gt;
  &lt;ex:p id="delta" xmlns:ex="http://example.com/ns"&gt;Three&lt;/ex:p&gt;
  &lt;?pi 3.14159?&gt;
&lt;/doc&gt;
         </eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">local-name($e//*[@id = 'alpha'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"p"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">local-name($e//*[@id = 'gamma'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"p"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">local-name($e//*[@id = 'delta'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"p"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">local-name($e//processing-instruction())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"pi"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">local-name($e//*[@id = 'alpha']/text())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">local-name($e//*[@id = 'alpha']/@id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"id"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">local-name($e//*[@id = 'alpha']/@xml:id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"id"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-name"><head>fn:name</head><glist><gitem><label>Summary</label><def><p>Returns the name of a node, as an <code nobreak="false">xs:string</code> that is either the zero-length
            string, or has the lexical form of an <code nobreak="false">xs:QName</code>. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="name" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, the function returns the zero-length string.</p><p>If the node identified by <code nobreak="false">$node</code> has no name (that is, if it is a document
            node, a comment, a text node, or a namespace node having no name), the function returns
            the zero-length string.</p><p>Otherwise, the function returns the value of the expression
               <code nobreak="false">fn:string(fn:node-name($node))</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">node()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>Because the result depends on the choice of namespace prefixes in the source document,
         it is not good practice to use the result of this function for anything other than display
         purposes. For example, the test <code nobreak="false">name(.) = 'my:profile'</code> will fail if the source
         document uses an unexpected namespace prefix. Such a test (assuming it relates to an element node) 
         is better written as <code nobreak="false">boolean(self::my:profile)</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;doc&gt;
  &lt;p id="alpha" xml:id="beta"&gt;One&lt;/p&gt;
  &lt;p id="gamma" xmlns="http://example.com/ns"&gt;Two&lt;/p&gt;
  &lt;ex:p id="delta" xmlns:ex="http://example.com/ns"&gt;Three&lt;/ex:p&gt;
  &lt;?pi 3.14159?&gt;
&lt;/doc&gt;
         </eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">name($e//*[@id = 'alpha'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"p"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">name($e//*[@id = 'gamma'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"p"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">name($e//*[@id = 'delta'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"ex:p"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">name($e//processing-instruction())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"pi"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">name($e//*[@id = 'alpha']/text())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">name($e//*[@id = 'alpha']/@id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"id"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">name($e//*[@id = 'alpha']/@xml:id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"xml:id"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-namespace-uri"><head>fn:namespace-uri</head><glist><gitem><label>Summary</label><def><p>Returns the namespace URI part of the name of <code nobreak="false">$node</code>, as an
               <code nobreak="false">xs:anyURI</code> value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="namespace-uri" return-type="xs:anyURI" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, if the node identified by is neither an
            element nor an attribute node, or if it is an element or attribute node whose
            expanded-QName (as determined by the <code nobreak="false">dm:node-name</code> accessor in the
            <xspecref spec="DM40" ref="dm-node-name"/>) is in no namespace,
            then the function returns the zero-length <code nobreak="false">xs:anyURI</code> value.</p><p>Otherwise, the result will be the namespace URI part of the expanded-QName of the node
            identified by <code nobreak="false">$node</code>, as determined by the <code nobreak="false">dm:node-name</code> accessor
            defined in <xspecref spec="DM40" ref="dm-node-name"/>), returned as an
               <code nobreak="false">xs:anyURI</code> value.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">node()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;doc&gt;
  &lt;p id="alpha" xml:id="beta"&gt;One&lt;/p&gt;
  &lt;p id="gamma" xmlns="http://example.com/ns"&gt;Two&lt;/p&gt;
  &lt;ex:p id="delta" xmlns:ex="http://example.com/ns"&gt;Three&lt;/ex:p&gt;
  &lt;?pi 3.14159?&gt;
&lt;/doc&gt;
         </eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri($e//*[@id = 'alpha'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri($e//*[@id = 'gamma'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://example.com/ns"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri($e//*[@id = 'delta'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://example.com/ns"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri($e//processing-instruction())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri($e//*[@id = 'alpha']/text())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri($e//*[@id = 'alpha']/@id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">""</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri($e//*[@id = 'alpha']/@xml:id)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://www.w3.org/XML/1998/namespace"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-namespace-uri-for-prefix"><head>fn:namespace-uri-for-prefix</head><glist><gitem><label>Summary</label><def><p>Returns the namespace URI of one of the in-scope namespaces for <code nobreak="false">$element</code>,
            identified by its namespace prefix.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="namespace-uri-for-prefix" return-type="xs:anyURI?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:NCName | enum(''))?"/><arg name="element" type="element()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p diff="chg" at="A">The function returns the result of the expression <code nobreak="false">map:get(fn:in-scope-namespaces($element), string($value))</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := 
&lt;z:a xmlns="http://example.org/one" xmlns:z="http://example.org/two"&gt;
  &lt;b xmlns=""/&gt;
&lt;/z:a&gt;</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri-for-prefix("z", $e)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://example.org/two"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri-for-prefix("", $e)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://example.org/one"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri-for-prefix((), $e)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://example.org/one"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">namespace-uri-for-prefix("xml", $e)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"http://www.w3.org/XML/1998/namespace"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-path"><head>fn:path</head><changes><change issue="332 1660" PR="1620 1886" date="2024-11-29">Options are added to customize the form of the output.</change><change issue="2100" PR="2149" date="2025-08-05">The function is extended to handle JNodes.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a path expression that can be used to select the supplied node relative to the
            root of its containing document.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="path" return-type="xs:string?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="gnode()?" default="."/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, the function returns the empty sequence.</p><p>The <code nobreak="false">$options</code> argument defines additional parameters controlling
            how the output is formatted. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply. The options available are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="origin" type="gnode()?" occur="opt"/><arg name="lexical" type="xs:boolean" occur="opt"/><arg name="namespaces" type="map((xs:NCName | enum('')), xs:anyURI)?" occur="opt"/><arg name="indexes" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">origin?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">A GNode, which must be an ancestor of <code nobreak="false">$node</code>. If present,
                  the returned path will be a relative path that selects <code nobreak="false">$node</code>
                  starting from the supplied origin node, rather than from the root of the
                  containing tree.
               <ulist><item><p><term>Type: </term><code nobreak="false">gnode()?</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">lexical?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">If true, the names of element nodes in the path are represented by the
                  result of a call on the <function>name</function> function applied to each element. The
                  result in this case does not contain sufficient information to identify the
                  namespace URI of the element.
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">namespaces?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">A map from namespace prefixes to namespace URIs, such as might be returned
                  by the function <function>fn:in-scope-namespaces</function>. If a prefix is available
                  for a given URI, it is used in preference to using <code nobreak="false">Q{uri}local</code> notation.
               <ulist><item><p><term>Type: </term><code nobreak="false">map((xs:NCName | enum('')), xs:anyURI)?</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">indexes?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">If true, the returned path includes the index positions of nodes. If
                  false, only the node names are included.
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr></tbody></table><p>Let <var>R</var> be the GNode supplied in the <code nobreak="false">origin</code> option,
         or the root GNode of the tree containing <code nobreak="false">$node</code> otherwise.</p><p>If <code nobreak="false">$node</code> is a document node, or a JNode with no parent,
            the function returns the string <code nobreak="false">"/"</code>.</p><p>Otherwise, the function returns a string that consists of a sequence of steps, one
            for each ancestor-or-self of <code nobreak="false">$node</code> that is not an ancestor-or-self 
            of <var>R</var>.</p><p>If <var>R</var> is an XNode other than a document node and the <code nobreak="false">origin</code> option
            is absent or empty, then this string is preceded by
            a string notionally representing a call to the <code nobreak="false">fn:root</code> function, 
            expressed as follows:</p><ulist><item><p>If the <code nobreak="false">lexical</code> option is present with the value <code nobreak="false">true</code>,
            then the string <code nobreak="false">"fn:root()"</code>.</p></item><item><p>If the <code nobreak="false">namespaces</code> option is present and defines a mapping from a 
               non empty prefix <var>P</var> 
            to the namespace URI <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>, then
            <code nobreak="false">"<var>P</var>:root()"</code></p></item><item><p>If the <code nobreak="false">namespaces</code> option is present and defines a mapping from the empty string
            to the namespace URI <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>, then
            <code nobreak="false">"root()"</code></p></item><item><p>Otherwise, <code nobreak="false">"Q{http://www.w3.org/2005/xpath-functions}root()"</code>.</p></item></ulist><p>Each step is the concatenation of:</p><olist><item><p>The character <code nobreak="false">"/"</code>, which is omitted for the first step
            if the <code nobreak="false">origin</code> option is present;</p></item><item><p>A string whose form depends on the kind of node selected by that step, as
            follows:</p><olist><item><p>For an element node, the concatenation of:</p><olist><item><p>A representation of the element name, chosen as follows:</p><olist><item><p>If the <code nobreak="false">lexical</code> option is present with the value
                        <code nobreak="false">true</code>, then the result of applying the <function>name</function>
                        function to the element node.</p></item><item><p>Otherwise, if the <code nobreak="false">namespaces</code> option is present
                           and the element is in a namespace <var>U</var> and the <code nobreak="false">namespaces</code> option
                           includes a mapping from a prefix <var>P</var> to the namespace <var>U</var>,
                           then the string <code nobreak="false"><var>P</var>:<var>L</var></code>, where <var>L</var>
                           is the local part of the element name.
                           If there is more than one such prefix, then one of them is chosen arbitrarily.</p></item><item><p>Otherwise, if the <code nobreak="false">namespaces</code> option is present
                           and the element is in a namespace <var>U</var> and the <code nobreak="false">namespaces</code> option
                           includes a mapping from the zero-length string to the namespace <var>U</var>,
                           then the local part of the element name.</p></item><item><p>Otherwise, if the <code nobreak="false">namespaces</code> option is present
                           and the element is in no namespace and the <code nobreak="false">namespaces</code> option
                           includes no mapping from the zero-length string to any namespace,
                           then the local part of the element name.</p></item><item><p>Otherwise, the string <code nobreak="false">Q{<var>U</var>}<var>L</var></code>,
                        where <var>U</var> is the namespace URI of the element name or the
                        empty string if the element is in no namespace, and <var>L</var> is
                        the local part of the element name.</p></item></olist></item><item><p>Unless the <code nobreak="false">indexes</code> option is present
                     with the value <code nobreak="false">false</code>,
                     a string in the form <code nobreak="false">[<var>position</var>]</code> where <var>position</var> is an
                        integer representing the one-based position of the selected node among its like-named
                        siblings.</p></item></olist></item><item><p>For an attribute node, the concatenation of:</p><olist><item><p>The character <code nobreak="false">"@"</code></p></item><item><p>If the <code nobreak="false">lexical</code> option is present with the value
                        <code nobreak="false">true</code>, then the result of applying the <function>name</function>
                        function to the attribute node.</p></item><item><p>Otherwise, if the attribute node is in no namespace, the local part of the attribute name.</p></item><item><p>Otherwise, if the <code nobreak="false">namespaces</code> option is present, and if it includes a mapping
                        from a non-empty namespace prefix <var>P</var> to the namespace URI of the attribute, then
                        a string in the form <code nobreak="false"><var>P</var>:<var>L</var></code>, where <var>L</var>
                           is the local part of the attribute name.
                           If there is more than one such prefix, then one of them is chosen arbitrarily.</p></item><item><p>Otherwise, the string <code nobreak="false">Q{<var>U</var>}<var>L</var></code>,
                        where <var>U</var> is the namespace URI of the attribute name, and <var>L</var> is
                        the local part of the attribute name.</p></item></olist></item><item><p>For a text node: <code nobreak="false">text()[<var>position</var>]</code> where
                        <code nobreak="false"><var>position</var></code> is an integer representing the position
                  of the selected node among its text node siblings.</p><p>The suffix <code nobreak="false">[<var>position</var>]</code> is omitted if the <code nobreak="false">indexes</code>
               option is present with the value <code nobreak="false">false</code>.</p></item><item><p>For a comment node: <code nobreak="false">comment()[<var>position</var>]</code> where
                        <code nobreak="false"><emph>position</emph></code> is an integer representing the position
                  of the selected node among its comment node siblings.</p><p>The suffix <code nobreak="false">[<var>position</var>]</code> is omitted if the <code nobreak="false">indexes</code>
               option is present with the value <code nobreak="false">false</code>.</p></item><item><p>For a processing-instruction node:
                        <code nobreak="false">processing-instruction(<var>local</var>)[<var>position</var>]</code>
                  where <code nobreak="false"><emph>local</emph></code> is the name of the processing instruction
                  node and <code nobreak="false"><emph>position</emph></code> is an integer representing the
                  position of the selected node among its like-named processing-instruction node
                  siblings.</p><p>The suffix <code nobreak="false">[<var>position</var>]</code> is omitted if the <code nobreak="false">indexes</code>
               option is present with the value <code nobreak="false">false</code>.</p></item><item><p>For a namespace node:</p><olist><item><p>If the namespace node has a name:
                           <code nobreak="false">namespace::<emph>prefix</emph></code>, where
                              <code nobreak="false"><emph>prefix</emph></code> is the local part of the name of the
                        namespace node (which represents the namespace prefix).</p></item><item><p>If the namespace node has no name (that is, if it represents the default
                        namespace):
                           <code nobreak="false">namespace::*[<var>U</var>local-name() = ""]</code></p><p>Here <code nobreak="false"><var>U</var>local-name()</code> represents a call on the function
                        <code nobreak="false">fn:local-name</code> and is formatted using the same 
                        conventions as the call on <code nobreak="false">fn:root</code> described earlier.</p></item></olist></item><item><p>For a JNode where the ·jvalue· property of the parent
                     is an array, then as the string <code nobreak="false">*[<var>N</var>]</code> where <var>N</var>
                     is the value of the ·jkey· property.</p></item><item><p>For any other JNode (including the case where the ·jvalue· property of the parent
                     is a map):</p><olist><item><p>If the value is an <code nobreak="false">xs:string</code>, <code nobreak="false">xs:untypedAtomic</code>,
                     or <code nobreak="false">xs:anyURI</code> that is castable to <code nobreak="false">xs:NCName</code>, then
                     the result of casting the value to <code nobreak="false">xs:NCName</code>.</p></item><item><p>If the value is an <code nobreak="false">xs:string</code>, <code nobreak="false">xs:untypedAtomic</code>,
                     or <code nobreak="false">xs:anyURI</code> that is not castable to <code nobreak="false">xs:NCName</code>, then
                     then as the string <code nobreak="false">get("<var>S</var>")</code>
                     where <var>S</var> is the string value.</p></item><item><p>If the value is numeric, then as the string <code nobreak="false">get(<var>N</var>)</code>
                     where <var>N</var> is the result of casting the numeric value to 
                        <code nobreak="false">xs:string</code>.</p></item><item><p>If the value is an <code nobreak="false">xs:QName</code>, then as the string
                     <code nobreak="false">get(#Q{<var>uri</var>}<var>local</var>)</code> where <var>uri</var>
                     and <var>local</var> are the namespace URI and local name parts of the QName.</p></item><item><p>If the value is an <code nobreak="false">xs:boolean</code>, then as the string
                     <code nobreak="false">get(true())</code> or <code nobreak="false">get(false())</code>.</p></item><item><p>If the value is of any other type, then as the string
                     <code nobreak="false">get(xs:<var>T</var>("<var>S</var>"))</code> where <var>T</var> is the
                        local part of the most specific built-in atomic type of which the value
                        is an instance, and <var>S</var> is the result of casting the value to 
                           <code nobreak="false">xs:string</code>.</p></item></olist><p>TODO: Better handling of the case where the parent is neither a map nor an array,
                  for example where it is a sequence of several maps or several arrays. It's hard to
                  provide a better path for these when there is no AxisStep for selecting within
                  such values.</p></item></olist></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">node()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist><p>If the value of the <code nobreak="false">origin</code> option is a node that is not an ancestor
                  of <code nobreak="false">$node</code> (or in the absence of <code nobreak="false">$node</code>, the context value), 
                  dynamic error <errorref spec="FO" class="PA" code="0001" type="dynamic"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Using the <code nobreak="false">namespaces</code> option to shorten the generated path is often convenient,
         but the resulting path may be unusable if the input tree contains multiple bindings for the same prefix.</p><p>Similarly, using the <code nobreak="false">lexical</code> option is convenient if there is no need for precise
         namespace information: it is especially suitable when the containing node tree declares no namespaces.</p><p>If the supplied argument is a map or an array, it will automatically be coerced to a JNode. This
         however is not useful, because this will be a root JNode, yielding the path <code nobreak="false">/</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := document {            
  &lt;p xmlns="http://example.com/one" xml:lang="de" author="Friedrich von Schiller"&gt;
Freude, schöner Götterfunken,&lt;br/&gt;
Tochter aus Elysium,&lt;br/&gt;
Wir betreten feuertrunken,&lt;br/&gt;
Himmlische, dein Heiligtum.
&lt;/p&gt;}
         </eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $emp := 
  &lt;employee xml:id="ID21256"&gt;
     &lt;empnr&gt;E21256&lt;/empnr&gt;
     &lt;first&gt;John&lt;/first&gt;
     &lt;last&gt;Brown&lt;/last&gt;
  &lt;/employee&gt;
         </eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/Q{http://example.com/one}p[1]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p, { 'namespaces': in-scope-namespaces($e/*) })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/p[1]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p, { 'indexes': false() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/Q{http://example.com/one}p'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p/@xml:lang)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/Q{http://example.com/one}p[1]/@Q{http://www.w3.org/XML/1998/namespace}lang'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e//@xml:lang, { 'namespaces': in-scope-namespaces($e/*) })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/p[1]/@xml:lang'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p/@author)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/Q{http://example.com/one}p[1]/@author'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p/*:br[2])</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/Q{http://example.com/one}p[1]/Q{http://example.com/one}br[2]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p/*:br[2], {
  'namespaces': { 'N': 'http://example.com/one' },
  'indexes': false() 
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/N:p/N:br'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e//text()[starts-with(normalize-space(), 'Tochter')])</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/Q{http://example.com/one}p[1]/text()[2]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p/*:br[2], { 'lexical': true() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'/p[1]/br[2]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($e/*:p/*:br[2], { 'lexical': true(), 'origin': $e/*:p })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'br[2]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($emp)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'Q{http://www.w3.org/2005/xpath-functions}root()'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($emp/@xml:id)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'Q{http://www.w3.org/2005/xpath-functions}root()/@Q{http://www.w3.org/XML/1998/namespace}id'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($emp/empnr)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'Q{http://www.w3.org/2005/xpath-functions}root()/Q{}empnr[1]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($emp/empnr, { 'lexical': true() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'fn:root()/empnr[1]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">path($emp/empnr, {
  'namespaces': {
    'fn': 'http://www.w3.org/2005/xpath-functions',
    '': ''
  }
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'fn:root()/empnr[1]'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $in := [ { "b": [ 3, 4 ] } ]
return path($in/*[1]/b/*[2])</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"/*[1]/b/*[2]"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $in := [ [ { 'a': 1 } ], [ { 'a': 2 } ] ]
return path($in//a[. = 2])</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"/*[2]/*[1]/a"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-root"><head>fn:root</head><glist><gitem><label>Summary</label><def><p>Returns the root of the tree to which <code nobreak="false">$node</code> belongs. The
         function can be applied both to <xtermref spec="DM40" ref="dt-XNode">XNodes</xtermref>
         and to <xtermref spec="DM40" ref="dt-JNode">JNodes</xtermref>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="root" return-type="gnode()?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="gnode()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the value of the expression
               <code nobreak="false">$node/ancestor-or-self::gnode()[last()]</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type
               <code nobreak="false">gnode()?</code>, type error
               <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>These examples use some variables which could be defined in <bibref ref="xquery-40"/>
               as:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $i := &lt;tool&gt;wrench&lt;/tool&gt;
let $o := &lt;order&gt;{ $i }&lt;quantity&gt;5&lt;/quantity&gt;&lt;/order&gt;
let $odoc := document { $o }
let $newi := $o/tool</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Or they could be defined in <bibref ref="xslt-40"/> as:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">&lt;xsl:variable name="i" as="element()"&gt;
  &lt;tool&gt;wrench&lt;/tool&gt;
&lt;/xsl:variable&gt;

&lt;xsl:variable name="o" as="element()"&gt;
  &lt;order&gt;
    &lt;xsl:copy-of select="$i"/&gt;
    &lt;quantity&gt;5&lt;/quantity&gt;
  &lt;/order&gt;
&lt;/xsl:variable&gt;

&lt;xsl:variable name="odoc"&gt;
  &lt;xsl:copy-of select="$o"/&gt;
&lt;/xsl:variable&gt;

&lt;xsl:variable name="newi" select="$o/tool"/&gt;</eg></td></tr><tr><td colspan="2" rowspan="1"><p><code nobreak="false">root($i)</code> returns the element node <code nobreak="false">$i</code>
            </p></td></tr><tr><td colspan="2" rowspan="1"><p><code nobreak="false">root($o/quantity)</code> returns the element node <code nobreak="false">$o</code>
            </p></td></tr><tr><td colspan="2" rowspan="1"><p><code nobreak="false">root($odoc//quantity)</code> returns the document node <code nobreak="false">$odoc</code>
            </p></td></tr><tr><td colspan="2" rowspan="1"><p><code nobreak="false">root($newi)</code> returns the element node <code nobreak="false">$o</code>
            </p></td></tr><tr><td colspan="2" rowspan="1"><p>The final three examples could be made type-safe by wrapping their operands with
                  <code nobreak="false">exactly-one()</code>.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-siblings"><head>fn:siblings</head><changes><change issue="1542 1552" PR="1547 1551" date="2024-11-05">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the supplied GNode together with its siblings, in document order.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="siblings" return-type="gnode()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="gnode()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If the value of <code nobreak="false">$node</code> is the empty sequence, the function returns the empty sequence.</p><p>If <code nobreak="false">$node</code> is a child of some parent GNode <var>P</var>, the function returns all the
         children of <var>P</var> (including <code nobreak="false">$node</code>), in document order, as determined
            by the value of <code nobreak="false">$node/child::gnode()</code>.</p><p>Otherwise (specifically, if <code nobreak="false">$node</code> is parentless, or if it is an attribute or namespace node),
         the function returns <code nobreak="false">$node</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">if ($node intersect $node/parent::node()/child::node())
then $node/parent::node()/child::node()
else $node</eg></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">node()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>The result of <code nobreak="false">siblings($n)</code> (except in error cases) is the same as
         the result of <code nobreak="false">$n/(preceding-sibling::node() | following-sibling-or-self::node())</code>.
         It is also the same as <code nobreak="false">$n/(preceding-sibling-or-self::node() | following-sibling::node())</code></p><p>As with names such as <code nobreak="false">parent</code> and <code nobreak="false">child</code>, the word <term>sibling</term>
         used here as a technical term is not a precise match to its use in describing human family relationships,
         but is chosen for convenience.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;doc x="X"&gt;&lt;a&gt;A&lt;/a&gt;text&lt;?pi 3.14159?&gt;&lt;/doc&gt;</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">siblings($e//a) ! string()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"A", "text", "3.14159"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">siblings($e//processing-instruction('pi')) ! string()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"A", "text", "3.14159"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">siblings($e//@x) ! string()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"X"</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="functions-on-node-sequences"><head>Functions on sequences of nodes</head><p>This section specifies functions on sequences of nodes.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:distinct-ordered-nodes</code></td><td rowspan="1" colspan="1">Removes duplicate GNodes and sorts the input into document order.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:innermost</code></td><td rowspan="1" colspan="1">Returns every GNode within the input sequence that is not an ancestor of another member
            of the input sequence; the GNodes are returned in document order with duplicates
            eliminated.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:outermost</code></td><td rowspan="1" colspan="1">Returns every GNode within the input sequence that has no ancestor that is itself a
            member of the input sequence; the nodes are returned in document order with duplicates
            eliminated.</td></tr></tbody></table><div3 id="func-distinct-ordered-nodes"><head>fn:distinct-ordered-nodes</head><changes><change issue="1189" PR="1191" date="2024-05-14">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Removes duplicate GNodes and sorts the input into document order.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="distinct-ordered-nodes" return-type="gnode()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="nodes" type="gnode()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Any duplicate GNodes (that is, XNodes or JNodes) in the input 
            (based on node identity) are discarded. The remaining GNodes
         are returned in <xtermref spec="XP40" ref="dt-document-order">document order</xtermref>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Document order is <termref def="implementation-dependent"/> (but stable) for
         GNodes in different trees. If some GNode in tree <var>A</var>
         precedes some GNode in tree <var>B</var>, then every GNode in <var>A</var> precedes
         every GNode in <var>B</var>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $x := parse-xml('&lt;doc&gt;&lt;a/&gt;&lt;b/&gt;&lt;c/&gt;&lt;d/&gt;&lt;c/&gt;&lt;e/&gt;&lt;/doc&gt;')
return distinct-ordered-nodes(($x//c, $x//b, $x//a, $x//b)) ! name()
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"a", "b", "c", "c"</eg><p><emph>(The two <code nobreak="false">$x//b</code> expressions select the same node; one of these
               is eliminated as a duplicate. The <code nobreak="false">$x//c</code> expression selects two nodes
               that have distinct identity, so both are retained.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $x := [ 1, "a", true() ]
return count(distinct-ordered-nodes(
  ($x/*[1], $x/jnode(*, xs:integer)) 
)) 
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg><p><emph>(The first array member is selected by two different
                  routes; duplicate JNodes are eliminated.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-innermost"><head>fn:innermost</head><changes><change issue="2100" PR="2149" date="2025-08-12">Generalized to work with JNodes as well as XNodes.</change></changes><glist><gitem><label>Summary</label><def><p>Returns every GNode within the input sequence that is not an ancestor of another member
            of the input sequence; the GNodes are returned in document order with duplicates
            eliminated.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="innermost" return-type="gnode()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="nodes" type="gnode()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The effect of the function call <code nobreak="false">fn:innermost($nodes)</code> is defined to be
            equivalent to the result of the expression:</p><eg xml:space="preserve">$nodes except $nodes/ancestor::gnode()</eg><p>That is, the function takes as input a sequence of GNodes, and returns every GNode within
            the sequence that is not an ancestor of another GNode within the sequence; the GNodes are
            returned in document order with duplicates eliminated.</p></def></gitem><gitem><label>Notes</label><def><note><p>If the supplied argument includes a map or an array, it will automatically be coerced to a JNode.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
"&lt;doc&gt;&lt;div id='a'&gt;&lt;div id='b'&gt;&lt;div id='c'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/doc&gt;"
-&gt; parse-xml(.)//div
-&gt; innermost(.)
-&gt; for-each(., fn { string(@id) })
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"c"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
[ [ [ 1, 2 ], [ 3, 4 ] ], [ [ 5, 6 ], [ 7, 8 ] ] ]
  //jnode(*, array(*))
=&gt; innermost() =!&gt; jvalue()
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, 2 ], [ 3, 4 ], [ 5, 6 ], [ 7, 8 ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-outermost"><head>fn:outermost</head><changes><change issue="2100" PR="2149" date="2025-08-12">Generalized to work with JNodes as well as XNodes.</change></changes><glist><gitem><label>Summary</label><def><p>Returns every GNode within the input sequence that has no ancestor that is itself a
            member of the input sequence; the nodes are returned in document order with duplicates
            eliminated.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="outermost" return-type="gnode()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="nodes" type="gnode()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The effect of the function call <code nobreak="false">fn:outermost($nodes)</code> is defined to be
            equivalent to the result of the expression:</p><eg xml:space="preserve">$nodes[not(ancestor::gnode() intersect $nodes)]/.</eg><p>That is, the function takes as input a sequence of GNodes, and returns every GNode within
            the sequence that does not have another GNode within the sequence as an ancestor; the
            GNodes are returned in document order with duplicates eliminated.</p></def></gitem><gitem><label>Notes</label><def><note><p>The formulation <code nobreak="false">$nodes except $nodes/descendant::node()</code> might appear to be
            simpler, but does not correctly account for attribute nodes, as these are not
            descendants of their parent element.</p><p>The motivation for the function was based on XSLT streaming use cases. There are cases
            where the <bibref ref="xslt-40"/> streaming rules allow the construct
               <code nobreak="false">outermost(//section)</code> but do not allow <code nobreak="false">//section</code>; the
            function can therefore be useful in cases where it is known that sections will not be
            nested, as well as cases where the application actually wishes to process all sections
            except those that are nested within another.</p><p>If the supplied argument includes a map or an array, it will automatically be coerced to a JNode.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
"&lt;doc&gt;&lt;div id='a'&gt;&lt;div id='b'&gt;&lt;div id='c'/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/doc&gt;"
-&gt; parse-xml(.)//div
-&gt; outermost(.)
-&gt; for-each(., fn { string(@id) })
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"a"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
[ [ [ 1 ], [ 2 ] ], [ [ 3 ], [ 4 ] ], [ [ 5 ], [ 6 ] ] ]
  //self::jnode(*, array(*))
=&gt; outermost() =!&gt; array:size()
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">3</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="fns-on-identifiers"><head>Identifying nodes</head><p>This section defines a number of functions used to find elements by <code nobreak="false">ID</code> or <code nobreak="false">IDREF</code> value, 
               or to generate identifiers.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:id</code></td><td rowspan="1" colspan="1">Returns the sequence of element nodes that have an <code nobreak="false">ID</code> value matching the
            value of one or more of the <code nobreak="false">IDREF</code> values supplied in <code nobreak="false">$values</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:element-with-id</code></td><td rowspan="1" colspan="1"> Returns the sequence of element nodes that have an <code nobreak="false">ID</code> value matching the
            value of one or more of the <code nobreak="false">IDREF</code> values supplied in <code nobreak="false">$values</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:idref</code></td><td rowspan="1" colspan="1">Returns the sequence of element or attribute nodes with an <code nobreak="false">IDREF</code> value
            matching the value of one or more of the <code nobreak="false">ID</code> values supplied in
               <code nobreak="false">$values</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:generate-id</code></td><td rowspan="1" colspan="1">This function returns a string that uniquely identifies a given GNode. </td></tr></tbody></table><div3 id="func-id"><head>fn:id</head><glist><gitem><label>Summary</label><def><p>Returns the sequence of element nodes that have an <code nobreak="false">ID</code> value matching the
            value of one or more of the <code nobreak="false">IDREF</code> values supplied in <code nobreak="false">$values</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="id" return-type="element()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:string*"/><arg name="node" type="node()" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence, in document order with duplicates eliminated,
            containing every element node <code nobreak="false">E</code> that satisfies all the following
            conditions:</p><olist><item><p>
                  <code nobreak="false">E</code> is in the target document. The target document is the document
                  containing <code nobreak="false">$node</code>.</p></item><item><p><code nobreak="false">E</code> has an <code nobreak="false">ID</code> value equal to one of the candidate
                     <code nobreak="false">IDREF</code> values, where:</p><ulist><item><p> An element has an <code nobreak="false">ID</code> value equal to <code nobreak="false">V</code> if either
                        or both of the following conditions are true:</p><ulist><item><p>The <code nobreak="false">is-id</code> property (See <xspecref spec="DM40" ref="dm-is-id"/>.) of the element node is <code nobreak="false">true</code>, and the typed value
                              of the element node is equal to <code nobreak="false">V</code> under the rules of the
                                 <code nobreak="false">eq</code> operator using the Unicode codepoint collation
                                 (<code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item><item><p>The element has an attribute node whose <code nobreak="false">is-id</code> property
                              (See <xspecref spec="DM40" ref="dm-is-id"/>.) is <code nobreak="false">true</code> and whose typed
                              value is equal to <code nobreak="false">V</code> under the rules of the
                                 <code nobreak="false">eq</code> operator using the Unicode code point collation
                                 (<code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p> Each <code nobreak="false">xs:string</code> in <code nobreak="false">$values</code> is parsed as if it were of
                        type <code nobreak="false">IDREFS</code>, that is, each <code nobreak="false">xs:string</code> in
                        <code nobreak="false">$values</code> is treated as a whitespace-separated sequence of
                        tokens, each acting as an <code nobreak="false">IDREF</code>. These tokens are then included
                        in the list of candidate <code nobreak="false">IDREF</code>s. If any of the tokens is not a
                        lexically valid <code nobreak="false">IDREF</code> (that is, if it is not lexically an
                           <code nobreak="false">xs:NCName</code>), it is ignored. Formally, the candidate
                           <code nobreak="false">IDREF</code> values are the strings in the sequence given by the
                        expression:</p><eg xml:space="preserve">for $s in $values
return tokenize(normalize-space($s), ' ')[. castable as xs:IDREF]</eg></item></ulist></item><item><p>If several elements have the same <code nobreak="false">ID</code> value, then <code nobreak="false">E</code> is
                  the one that is first in document order.</p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0001" type="dynamic"/> if
               <code nobreak="false">$node</code>, or the context value if the second argument is absent, is a node
            in a tree whose root is not a document node.</p><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not a single node, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>The effect of this function is anomalous in respect of element nodes with the
               <code nobreak="false">is-id</code> property. For legacy reasons, this function returns the element
            that has the <code nobreak="false">is-id</code> property, whereas it would be more appropriate to return
            its parent, that being the element that is uniquely identified by the ID. A new function
               <function>fn:element-with-id</function> has been introduced with the desired
            behavior.</p><p> If the data model is constructed from an Infoset, an attribute will have the
               <code nobreak="false">is-id</code> property if the corresponding attribute in the Infoset had an
            attribute type of <code nobreak="false">ID</code>: typically this means the attribute was declared as an
               <code nobreak="false">ID</code> in a DTD.</p><p> If the data model is constructed from a PSVI, an element or attribute will have the
               <code nobreak="false">is-id</code> property if its typed value is a single atomic item of type
               <code nobreak="false">xs:ID</code> or a type derived by restriction from <code nobreak="false">xs:ID</code>.</p><p> No error is raised in respect of a candidate <code nobreak="false">IDREF</code> value that does not
            match the <code nobreak="false">ID</code> of any element in the document. If no candidate
               <code nobreak="false">IDREF</code> value matches the <code nobreak="false">ID</code> value of any element, the
            function returns the empty sequence.</p><p> It is not necessary that the supplied argument should have type <code nobreak="false">xs:IDREF</code>
            or <code nobreak="false">xs:IDREFS</code>, or that it should be derived from a node with the
               <code nobreak="false">is-idrefs</code> property.</p><p> An element may have more than one <code nobreak="false">ID</code> value. This can occur with synthetic
            data models or with data models constructed from a PSVI where the element and one of its
            attributes are both typed as <code nobreak="false">xs:ID</code>.</p><p> If the source document is well-formed but not valid, it is possible for two or more
            elements to have the same <code nobreak="false">ID</code> value. In this situation, the function will
            select the first such element.</p><p> It is also possible in a well-formed but invalid document to have an element or
            attribute that has the <code nobreak="false">is-id</code> property but whose value does not conform to
            the lexical rules for the <code nobreak="false">xs:ID</code> type. Such a node will never be selected by
            this function.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $emp := validate lax {
  document {
    &lt;employee xml:id="ID21256"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
              xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
      &lt;empnr xsi:type="xs:ID"&gt;E21256&lt;/empnr&gt;
      &lt;first&gt;John&lt;/first&gt;
      &lt;last&gt;Brown&lt;/last&gt;
    &lt;/employee&gt;
  }
}</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">$emp/id('ID21256')/name()</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"employee"</eg><p><emph>(The <code nobreak="false">xml:id</code> attribute has the <code nobreak="false">is-id</code> property,
                  so the employee element is selected.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">$emp/id('E21256')/name()</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"empnr"</eg><p><emph>(Assuming the <code nobreak="false">empnr</code> element is given the type
                     <code nobreak="false">xs:ID</code> as a result of schema validation, the element will have the
                     <code nobreak="false">is-id</code> property and is therefore selected. Note the difference from
                  the behavior of <function>fn:element-with-id</function>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-element-with-id"><head>fn:element-with-id</head><glist><gitem><label>Summary</label><def><p> Returns the sequence of element nodes that have an <code nobreak="false">ID</code> value matching the
            value of one or more of the <code nobreak="false">IDREF</code> values supplied in <code nobreak="false">$values</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="element-with-id" return-type="element()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:string*"/><arg name="node" type="node()" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><note><p>The effect of this function is identical to <function>fn:id</function> in respect of
               elements that have an attribute with the <code nobreak="false">is-id</code> property. However, it
               behaves differently in respect of element nodes with the <code nobreak="false">is-id</code> property.
               Whereas the <function>fn:id</function> function, for legacy reasons, returns the element that has the
                  <code nobreak="false">is-id</code> property, this function returns the element identified by the ID,
               which is the parent of the element having the <code nobreak="false">is-id</code> property.</p></note><p>The function returns a sequence, in document order with duplicates eliminated,
            containing every element node <code nobreak="false">E</code> that satisfies all the following
            conditions:</p><olist><item><p>
                  <code nobreak="false">E</code> is in the target document. The target document is the document
                  containing <code nobreak="false">$node</code>.</p></item><item><p><code nobreak="false">E</code> has an <code nobreak="false">ID</code> value equal to one of the candidate
                     <code nobreak="false">IDREF</code> values, where:</p><ulist><item><p> An element has an <code nobreak="false">ID</code> value equal to <code nobreak="false">V</code> if either
                        or both of the following conditions are true:</p><ulist><item><p>The element has an child element node whose <code nobreak="false">is-id</code>
                              property (See <xspecref spec="DM40" ref="dm-is-id"/>.) is <code nobreak="false">true</code> and
                              whose typed value is equal to <code nobreak="false">V</code> under the rules of the
                                 <code nobreak="false">eq</code> operator using the Unicode code point collation
                                 (<code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item><item><p>The element has an attribute node whose <code nobreak="false">is-id</code> property
                              (See <xspecref spec="DM40" ref="dm-is-id"/>.) is <code nobreak="false">true</code> and whose typed
                              value is equal to <code nobreak="false">V</code> under the rules of the
                                 <code nobreak="false">eq</code> operator using the Unicode code point collation
                                 (<code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p>Each <code nobreak="false">xs:string</code> in <code nobreak="false">$values</code> is parsed as if it were of
                        type <code nobreak="false">IDREFS</code>, that is, each <code nobreak="false">xs:string</code> in
                        <code nobreak="false">$values</code> is treated as a whitespace-separated sequence of
                        tokens, each acting as an <code nobreak="false">IDREF</code>. These tokens are then included
                        in the list of candidate <code nobreak="false">IDREF</code>s. If any of the tokens is not a
                        lexically valid <code nobreak="false">IDREF</code> (that is, if it is not lexically an
                           <code nobreak="false">xs:NCName</code>), it is ignored. Formally, the candidate
                           <code nobreak="false">IDREF</code> values are the strings in the sequence given by the
                        expression:</p><eg xml:space="preserve">for $s in $values
return tokenize(normalize-space($s), ' ')[. castable as xs:IDREF]</eg></item></ulist></item><item><p> If several elements have the same <code nobreak="false">ID</code> value, then <code nobreak="false">E</code> is
                  the one that is first in document order.</p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0001" type="dynamic"/> if <code nobreak="false">$node</code>, or the context value if the second argument is omitted, is a node
            in a tree whose root is not a document node.</p><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>, type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not a single node, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>This function is equivalent to the <function>fn:id</function> function except when dealing with
            ID-valued element nodes. Whereas the <function>fn:id</function> function selects the element
            containing the identifier, this function selects its parent.</p><p>If the data model is constructed from an Infoset, an attribute will have the
               <code nobreak="false">is-id</code> property if the corresponding attribute in the Infoset had an
            attribute type of <code nobreak="false">ID</code>: typically this means the attribute was declared as an
               <code nobreak="false">ID</code> in a DTD.</p><p> If the data model is constructed from a PSVI, an element or attribute will have the
               <code nobreak="false">is-id</code> property if its typed value is a single atomic item of type
               <code nobreak="false">xs:ID</code> or a type derived by restriction from <code nobreak="false">xs:ID</code>.</p><p> No error is raised in respect of a candidate <code nobreak="false">IDREF</code> value that does not
            match the <code nobreak="false">ID</code> of any element in the document. If no candidate
               <code nobreak="false">IDREF</code> value matches the <code nobreak="false">ID</code> value of any element, the
            function returns the empty sequence.</p><p> It is not necessary that the supplied argument should have type <code nobreak="false">xs:IDREF</code>
            or <code nobreak="false">xs:IDREFS</code>, or that it should be derived from a node with the
               <code nobreak="false">is-idrefs</code> property.</p><p> An element may have more than one <code nobreak="false">ID</code> value. This can occur with synthetic
            data models or with data models constructed from a PSVI where the element and one of its
            attributes are both typed as <code nobreak="false">xs:ID</code>.</p><p> If the source document is well-formed but not valid, it is possible for two or more
            elements to have the same <code nobreak="false">ID</code> value. In this situation, the function will
            select the first such element.</p><p> It is also possible in a well-formed but invalid document to have an element or
            attribute that has the <code nobreak="false">is-id</code> property but whose value does not conform to
            the lexical rules for the <code nobreak="false">xs:ID</code> type. Such a node will never be selected by
            this function.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $emp := validate lax {    
  document {
    &lt;employee xml:id="ID21256"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
              xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
      &lt;empnr xsi:type="xs:ID"&gt;E21256&lt;/empnr&gt;
      &lt;first&gt;John&lt;/first&gt;
      &lt;last&gt;Brown&lt;/last&gt;
    &lt;/employee&gt;
  }
}
         </eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">$emp/element-with-id('ID21256')/name()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"employee"</eg><p><emph>(The <code nobreak="false">xml:id</code> attribute has the <code nobreak="false">is-id</code> property,
                  so the employee element is selected.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">$emp/element-with-id('E21256')/name()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"employee"</code></p><p><emph>(Assuming the <code nobreak="false">empnr</code> element is given the type
                     <code nobreak="false">xs:ID</code> as a result of schema validation, the element will have the
                     <code nobreak="false">is-id</code> property and is therefore its parent is selected. Note the
                  difference from the behavior of <function>fn:id</function>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-idref"><head>fn:idref</head><glist><gitem><label>Summary</label><def><p>Returns the sequence of element or attribute nodes with an <code nobreak="false">IDREF</code> value
            matching the value of one or more of the <code nobreak="false">ID</code> values supplied in
               <code nobreak="false">$values</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="idref" return-type="node()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="values" type="xs:string*"/><arg name="node" type="node()" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p> The function returns a sequence, in document order with duplicates eliminated,
            containing every element or attribute node <code nobreak="false">$N</code> that satisfies all the
            following conditions:</p><olist><item><p><code nobreak="false">$N</code> is in the target document. The target document is the document
                  containing <code nobreak="false">$node</code>.</p></item><item><p><code nobreak="false">$N</code> has an <code nobreak="false">IDREF</code> value equal to one of the candidate
                     <code nobreak="false">ID</code> values, where:</p><ulist><item><p>A node <code nobreak="false">$N</code> has an <code nobreak="false">IDREF</code> value equal to
                           <code nobreak="false">V</code> if both of the following conditions are true:</p><ulist><item><p>The <code nobreak="false">is-idrefs</code> property (see <xspecref spec="DM40" ref="dm-is-idrefs"/>) of <code nobreak="false">$N</code> is <code nobreak="false">true</code>.</p></item><item><p>The sequence </p><eg xml:space="preserve">tokenize(normalize-space(string($N)), ' ')</eg><p>contains a string that is
                              equal to <code nobreak="false">V</code> under the rules of the <code nobreak="false">eq</code>
                              operator using the Unicode code point collation
                                 (<code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>).</p></item></ulist></item><item><p>Each <code nobreak="false">xs:string</code> in <code nobreak="false">$values</code> is parsed as if it were of
                        lexically of type <code nobreak="false">xs:ID</code>. These <code nobreak="false">xs:string</code>s are then
                        included in the list of candidate <code nobreak="false">xs:ID</code>s. If any of the strings
                        in <code nobreak="false">$values</code> is not a lexically valid <code nobreak="false">xs:ID</code> (that is,
                        if it is not lexically an <code nobreak="false">xs:NCName</code>), it is ignored. More
                        formally, the candidate <code nobreak="false">ID</code> values are the strings in the
                        sequence:</p><eg xml:space="preserve">$values[. castable as xs:NCName]</eg></item></ulist></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0001" type="dynamic"/> if
               <code nobreak="false">$node</code>, or the context value if the second argument is omitted, is a node
            in a tree whose root is not a document node. </p><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not a single node, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p> An element or attribute typically acquires the <code nobreak="false">is-idrefs</code> property by being
            validated against the schema type <code nobreak="false">xs:IDREF</code> or <code nobreak="false">xs:IDREFS</code>, or
            (for attributes only) by being described as of type <code nobreak="false">IDREF</code> or
               <code nobreak="false">IDREFS</code> in a DTD.</p><p>Because the function is sensitive to the way in which the data model
         is constructed, calls on this function are not always interoperable.</p><p> No error is raised in respect of a candidate <code nobreak="false">ID</code> value that does not match
            the <code nobreak="false">IDREF</code> value of any element or attribute in the document. If no
            candidate <code nobreak="false">ID</code> value matches the <code nobreak="false">IDREF</code> value of any element or
            attribute, the function returns the empty sequence.</p><p> It is possible for two or more nodes to have an <code nobreak="false">IDREF</code> value that matches a
            given candidate <code nobreak="false">ID</code> value. In this situation, the function will return all
            such nodes. However, each matching node will be returned at most once, regardless how
            many candidate <code nobreak="false">ID</code> values it matches.</p><p> It is possible in a well-formed but invalid document to have a node whose
               <code nobreak="false">is-idrefs</code> property is <code nobreak="false">true</code> but that does not conform to the lexical
            rules for the <code nobreak="false">xs:IDREF</code> type. The effect of the above rules is that
            ill-formed candidate <code nobreak="false">ID</code> values and ill-formed <code nobreak="false">IDREF</code> values are
            ignored.</p><p>If the data model is constructed from a PSVI, the typed value of a node that has the
               <code nobreak="false">is-idrefs</code> property will contain at least one atomic item of type
               <code nobreak="false">xs:IDREF</code> (or a type derived by restriction from <code nobreak="false">xs:IDREF</code>).
            It may also contain atomic items of other types. These atomic items are treated as
            candidate <code nobreak="false">ID</code> values <phrase>if two conditions are met: their lexical form must be valid as an
               <code nobreak="false">xs:NCName</code>, and there must be at least one instance of <code nobreak="false">xs:IDREF</code>
            in the typed value of the node. If these conditions are not satisfied, such values are ignored.</phrase></p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $emp := validate lax {  
  document {    
    &lt;employees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
               xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;  
      &lt;employee xml:id="ID21256"&gt;
        &lt;empnr xsi:type="xs:ID"&gt;E21256&lt;/empnr&gt;
        &lt;first&gt;Anil&lt;/first&gt;
        &lt;last&gt;Singh&lt;/last&gt;
        &lt;deputy xsi:type="xs:IDREF"&gt;E30561&lt;/deputy&gt;
      &lt;/employee&gt;
      &lt;employee xml:id="ID30561"&gt;
        &lt;empnr xsi:type="xs:ID"&gt;E30561&lt;/empnr&gt;
        &lt;first&gt;John&lt;/first&gt;
        &lt;last&gt;Brown&lt;/last&gt;
        &lt;manager xsi:type="xs:IDREF"&gt;ID21256&lt;/manager&gt;
      &lt;/employee&gt;
    &lt;/employees&gt;
  }
}
         </eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">$emp/(
  element-with-id('ID21256')/@xml:id =&gt; idref()
)/ancestor::employee/last
=&gt; string()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Brown"</eg><p><emph>(Assuming that <code nobreak="false">manager</code> has the is-idref property, the call on <function>fn:idref</function> selects
                  the <code nobreak="false">manager</code> element. If, instead, the <code nobreak="false">manager</code> had a <code nobreak="false">ref</code>
               attribute with the is-idref property, the call on <function>fn:idref</function> would select the attribute node.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">$emp/(
  element-with-id('E30561')/empnr =&gt; idref()
)/ancestor::employee/last
=&gt; string()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Singh"</eg><p><emph>(Assuming that <code nobreak="false">employee/deputy</code> has the is-idref property, the call on <function>fn:idref</function> selects
                  the <code nobreak="false">deputy</code> element.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-generate-id"><head>fn:generate-id</head><glist><gitem><label>Summary</label><def><p>This function returns a string that uniquely identifies a given GNode. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="generate-id" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="gnode()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The zero-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p><p>The one-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$node</code> is the empty sequence, the result is the zero-length string.</p><p>In other cases, the function returns a string that uniquely identifies a given node.
            <phrase>More formally, it is guaranteed that within a single
             <termref def="execution-scope">execution scope</termref>, 
               <code nobreak="false">fn:codepoint-equal(fn:generate-id($N), fn:generate-id($M))</code> returns <code nobreak="false">true</code> 
               if and only if <code nobreak="false">($M is $N)</code> returns <code nobreak="false">true</code>.</phrase></p><p>The returned identifier <rfc2119>must</rfc2119> consist of ASCII alphanumeric characters
            and <rfc2119>must</rfc2119> start with an alphabetic character. Thus, the string is
            syntactically an XML name.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/></p></item><item><p>If the context value is not an instance of the sequence type
               <code nobreak="false">gnode()?</code>, type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>An implementation is free to generate an identifier in any convenient way provided that
            it always generates the same identifier for the same GNode and that different identifiers
            are always generated from different GNodes. An implementation is under no obligation to
            generate the same identifiers each time a document is transformed or queried.</p><p>There is no guarantee that a generated unique identifier will be distinct from any
            unique IDs specified in the source document.</p><p>There is no inverse to this function; it is not directly possible to find the GNode with
            a given generated ID. Of course, it is possible to search a given sequence of GNodes
            using an expression such as <code nobreak="false">$nodes[generate-id()=$id]</code>.</p><p>It is advisable, but not required, for implementations to generate IDs that are distinct
            even when compared using a case-blind collation.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>The primary use case for this function is to generate hyperlinks. For example, when
               generating HTML, an anchor for a given section <code nobreak="false">$sect</code> can be generated by
               writing (in either XSLT or XQuery):</p></td></tr><tr><td colspan="2" rowspan="1"><p>
               <code nobreak="false">&lt;a name="{ generate-id($sect) }"/&gt;</code>
            </p></td></tr><tr><td colspan="2" rowspan="1"><p>and a link to that section can then be produced with code such as:</p></td></tr><tr><td colspan="2" rowspan="1"><p>
               <code nobreak="false">see &lt;a href="#{ generate-id($sect) }"&gt;here&lt;/a&gt;</code>
            </p></td></tr><tr><td colspan="2" rowspan="1"><p>Note that anchors generated in this way will not necessarily be the same each time a
               document is republished.</p></td></tr><tr><td colspan="2" rowspan="1"><p>Since the keys in a map must be atomic items, it is possible to use generated IDs
               as surrogates for nodes when constructing a map. For example, in some implementations,
               testing whether a node <code nobreak="false">$N</code> is a member of a large node-set <code nobreak="false">$S</code>
               using the expression <code nobreak="false">exists($N intersect $S)</code> may be expensive; there
               may then be performance benefits in creating a map:</p></td></tr><tr><td colspan="2" rowspan="1"><p>
               <code nobreak="false">let $SMap := map:merge($S ! { generate-id(.) : . })</code>
            </p></td></tr><tr><td colspan="2" rowspan="1"><p>and then testing for membership of the node-set using:</p></td></tr><tr><td colspan="2" rowspan="1"><p>
               <code nobreak="false">map:contains($SMap, generate-id($N))</code>
            </p></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="functions-on-functions"><head>Processing function items</head><p>The functions included in this section operate on function items, that is, values referring to a function.</p><p><termdef id="dt-higher-order" term="higher-order">Functions that accept functions among their arguments,
               or that return functions in their result, are described in this specification as <term>higher-order</term>
               functions.</termdef> 
               <phrase diff="del" at="2023-01-29">Some host languages may exclude higher-order functions from the set of functions
            that they support, or may include such functions in an optional conformance feature.</phrase></p><note><p>Some functions such as <function>fn:parse-json</function> allow the option of supplying a callback function
            for example to define exception behavior. Where this is not essential to the use of the function,
            the function has not been classified as higher-order for this purpose; in applications where function items
            cannot be created, these particular options will not be available.</p></note><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:function-lookup</code></td><td rowspan="1" colspan="1">Returns <phrase diff="chg" at="2023-05-26">a function item</phrase> having a given name and arity, if there is one.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:function-name</code></td><td rowspan="1" colspan="1">Returns the name of the function identified by a function item.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:function-arity</code></td><td rowspan="1" colspan="1">Returns the arity of the function identified by a function item.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:function-identity</code></td><td rowspan="1" colspan="1">Returns a string representing the identity of a function item.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:function-annotations</code></td><td rowspan="1" colspan="1">Returns the annotations of the function item.</td></tr></tbody></table><div2 id="func-function-lookup"><head>fn:function-lookup</head><glist><gitem><label>Summary</label><def><p>Returns <phrase diff="chg" at="2023-05-26">a function item</phrase> having a given name and arity, if there is one.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="function-lookup" return-type="fn(*)?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="name" type="xs:QName"/><arg name="arity" type="xs:integer"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p diff="chg" at="2023-05-26">A call to <function>fn:function-lookup</function> starts by looking for a 
            <xtermref spec="XP40" ref="dt-function-definition">function definition</xtermref>
             in the named functions component of the dynamic context
            (specifically, the dynamic context of the call to <function>fn:function-lookup</function>),
            using the expanded QName supplied as <code nobreak="false">$name</code> and the arity supplied as
            <code nobreak="false">$arity</code>. There can be at most one such function definition.</p><p>If no function definition can be identified (by name and arity), then the empty sequence
            is returned.</p><p diff="chg" at="2023-05-26">If a function definition is identified, then a function item is obtained from the function
         definition using the same rules as for evaluation of a named function reference 
         (see <xspecref spec="XP40" ref="id-named-function-ref"/>). The captured context of
         the returned function item (if it is context dependent) is the static and dynamic context of 
         the call on <function>fn:function-lookup</function>.</p><p>If the arguments to <function>fn:function-lookup</function> identify a function that is present
            in the static context of the function call, the function will always return the same
            function that a static reference to this function would bind to. If there is no such
            function in the static context, then the results depend on what is present in the
            dynamic context, which is <termref def="implementation-defined">implementation-defined</termref>.</p></def></gitem><gitem><label>Error Conditions</label><def><p diff="add" at="2023-12-12">An error is raised if the identified function depends on
            components of the static or dynamic context that are not present, or that have
            unsuitable values. For example <xerrorref spec="XP" class="DY" code="0002" type="type"/> is raised for the call
            <code nobreak="false">function-lookup( #fn:name, 0 )</code>
            if the context value is absent, and <errorref class="DC" code="0001" type="dynamic"/> is raised for the call <code nobreak="false">function-lookup( #fn:id, 1 )</code> if the
            context value is not a single node in a tree that is rooted at a document node.
            The error that is raised is the same as the error that would be raised by the
            corresponding function if called with the same static and dynamic context.</p></def></gitem><gitem><label>Notes</label><def><note><p>This function can be useful where there is a need to make a dynamic decision on which of
            several statically known functions to call. It can thus be used as a substitute for
            polymorphism, in the case where the application has been designed so several functions
            implement the same interface.</p><p>The function can also be useful in cases where a query or stylesheet module is written
            to work with alternative versions of a library module. In such cases the author of the
            main module might wish to test whether an imported library module contains or does not
            contain a particular function, and to call a function in that module only if it is
            available in the version that was imported. A static call would cause a static error if
            the function is not available, whereas getting the function using
               <function>fn:function-lookup</function> allows the caller to take fallback action in this
            situation. </p><p>If the function that is retrieved by <function>fn:function-lookup</function> is <termref def="dt-context-dependent">context-dependent</termref>, that is, if it has
            dependencies on the static or dynamic context of its caller, the context that applies is
            the static and/or dynamic context of the call to the <function>fn:function-lookup</function>
            function itself. The context thus effectively forms part of the closure of the returned
            function. This mainly applies when the target of
               <function>fn:function-lookup</function> is a built-in function, because user-defined
            functions typically have no dependency on the static or dynamic context of the function call
            (an exception arises when the expressions used to define default values for parameters
            are context-dependent). The rule
            applies recursively, since <function>fn:function-lookup</function> is itself a context-dependent
            built-in function. </p><p>However, the static and dynamic context of the call to <function>fn:function-lookup</function>
            may play a role even when the selected function definition is not itself context dependent,
            if the expressions used to establish default parameter values are context dependent.</p><p>User-defined XSLT or XQuery functions should be accessible to <function>fn:function-lookup</function>
         only if they are statically visible at the location where the call to <function>fn:function-lookup</function>
         appears. This means that private functions, if they are not statically visible in the containing
         module, should not be accessible using <function>fn:function-lookup</function>.</p><p diff="add" at="2023-05-26">The function identity is determined in the same way as for
         a named function reference. Specifically, if there is no context dependency, two calls
         on <function>fn:function-lookup</function> with the same name and arity must return the same function.</p><p>These specifications do not define any circumstances in which the dynamic context will
            contain functions that are not present in the static context, but neither do they rule
            this out. For example an API <rfc2119>may</rfc2119> provide the ability to add functions
            to the dynamic context, and such functions may potentially be context-dependent. </p><p>The mere fact that a function exists and has a name does not of itself mean that the
         function is present in the dynamic context. For example, functions obtained through
         use of the <function>fn:load-xquery-module</function> function are not added to the dynamic context.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">function-lookup( #fn:substring, 2 )( 'abcd', 2 )</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">'bcd'</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">(fn:function-lookup( #xs:dateTimeStamp, 1 ),
                  xs:dateTime#1)[1] ('2011-11-11T11:11:11Z')</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>An
                  <code nobreak="false">xs:dateTime</code> value set to the specified date, time, and timezone; if
               the implementation supports XSD 1.1 then the result will be an instance of the
               derived type <code nobreak="false">xs:dateTimeStamp</code>. The query is written to ensure that no
               failure occurs when the implementation does not recognize the type
                  <code nobreak="false">xs:dateTimeStamp</code>.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">declare namespace zip = "http://expath.org/ns/zip";
let $f := function-lookup( #zip:binary-entry, 2 )
return if (exists($f)) then $f("file:///temp.zip", "index.xml") else ()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The result of
               calling <code nobreak="false">zip:binary-entry("file:///temp.zip", "index.xml")</code> if the function is available, or
               the empty sequence otherwise.</p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-function-name"><head>fn:function-name</head><glist><gitem><label>Summary</label><def><p>Returns the name of the function identified by a function item.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="function-name" return-type="xs:QName?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="function" type="fn(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$function</code> refers to a named function, <code nobreak="false">fn:function-name($func)</code>
            returns the name of that function.</p><p>Otherwise (<code nobreak="false">$function</code> refers to an anonymous function),
               <code nobreak="false">fn:function-name($function)</code> returns the empty sequence.</p><p>The prefix part of the returned QName is <termref def="implementation-dependent">implementation-dependent</termref>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">function-name(substring#2)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">#Q{http://www.w3.org/2005/xpath-functions}substring</eg><p><emph>(The namespace prefix of the returned QName is not predictable.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">function-name(fn($node) { count($node/*) })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-function-arity"><head>fn:function-arity</head><glist><gitem><label>Summary</label><def><p>Returns the arity of the function identified by a function item.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="function-arity" return-type="xs:integer" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="function" type="fn(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The <function>fn:function-arity</function> function returns the arity (number of arguments) of
            the function identified by <code nobreak="false">$function</code>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">function-arity(substring#2)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">function-arity(fn($node) { name($node) })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $initial := substring(?, 1, 1)
return function-arity($initial)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1</eg></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-function-identity"><head>fn:function-identity</head><changes><change issue="1798" PR="1801" date="2025-03-05">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a string representing the identity of a function item.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="function-identity" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="function" type="fn(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The <function>fn:function-identity</function> function returns a string that represents
            the identity of <code nobreak="false">$function</code>.</p><p>The returned string has the property that <code nobreak="false">fn:function-identity($f1)</code>
	      and <code nobreak="false">fn:function-identity($f2)</code> are codepoint-equal if and only if <code nobreak="false">$f1</code>
	      and <code nobreak="false">$f2</code> have the same function identity. Apart from this property, the
	      result is <termref def="implementation-dependent"/>.</p><p>In the case of maps and arrays, the result follows the following rule:
	        If <code nobreak="false">$X</code> and <code nobreak="false">$Y</code> are both maps or arrays then <code nobreak="false">fn:function-identity($X)</code>
	        <rfc2119>must not</rfc2119> be codepoint-equal to <code nobreak="false">fn:function-identity($Y)</code> unless
	        <code nobreak="false">$X</code> and <code nobreak="false">$Y</code> are indistinguishable, that is unless every operator or function applied
	        to <code nobreak="false">$X</code> returns the same result as for <code nobreak="false">$Y</code>. Even in this case, however, the
	        result of the comparison <code nobreak="false">fn:function-identity($X) eq fn:function-identity($Y)</code>
	        is <termref def="implementation-dependent"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>This function enables applications to test whether two expressions or variables
	        reference the same function item. This may be useful, for example, to allow caching
	        of function results to avoid repeated evaluation. The results of previous function
	        invocations might be held in a map whose key is the function identity.</p><p>The function identity, by definition, is generated upon the creation of a function item.
		   Specific expressions that create function items have their own rules for the identity
		   of the returned functions: for example, it is guaranteed that evaluation of a function
		   reference to a system function with no captured context (such as <code nobreak="false">fn:abs#1</code>)
		   will always return the same function item.</p><p>It is not meaningful to store or compare the result of calling <function>fn:function-identity</function> 
		   across different <termref def="execution-scope">execution scopes</termref>, because the string used 
		   to represent the function identity will generally vary from one execution scope to another.</p><p>The result of an expression such as <code nobreak="false">function-identity(abs#1) eq function-identity(abs(?))</code>
	     may be either <code nobreak="false">true</code> or <code nobreak="false">false</code>, because it is <termref def="implementation-dependent"/> 
	        whether <code nobreak="false">abs#1</code> and <code nobreak="false">abs(?)</code> return the same function item.</p><p>Similarly, <code nobreak="false">function-identity({ 1:() }) eq function-identity(map:entry(1, ()))</code>
	     may be either <code nobreak="false">true</code> or <code nobreak="false">false</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">function-identity(abs#1) eq function-identity(abs#1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">function-identity(abs#1) eq function-identity(round#1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">function-identity({ 1: 0 }) eq function-identity({ 1: 1 })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">function-identity([ 0 ]) eq function-identity([ 1 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-function-annotations"><head>fn:function-annotations</head><changes><change issue="36" PR="710" date="2023-09-17">New in 4.0</change><change issue="1391" PR="1393" date="2024-08-19">Changes the function to return a sequence of key-value pairs rather than a map.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the annotations of the function item.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="function-annotations" return-type="map(xs:QName, xs:anyAtomicType*)*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="function" type="fn(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The <code nobreak="false">fn:function-annotations</code> function returns the annotations of
            <code nobreak="false">$function</code> as a sequence of 
            <termref def="dt-single-entry-map">single-entry maps</termref>, each associating
            the name of a function annotation with the value of the annotation.
            Note that several annotations on a function can share the same name. The order
            of the annotations is retained.</p><p>The result is a sequence of <termref def="dt-single-entry-map">single-entry maps</termref>, 
            each being an instance of
            <code nobreak="false">map(xs:QName, xs:anyAtomicType*)</code>. 
            If a function (for example, a built-in function) has no annotations,
            the result of the function is the empty sequence.</p><p>For each annotation, a map is returned, with a single entry. The
            key of the map entry is the name of the annotation as an <code nobreak="false">xs:QName</code>.
            The value of the entry is the value of the annotation as a sequence of atomic items.
            If the annotation has no values, the associated value is the empty sequence.</p></def></gitem><gitem><label>Notes</label><def><note><p>In the common case where the annotation names are all unique, 
            the result of the function can readily be converted into single map by applying the function 
            <code nobreak="false">map:merge</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">function-annotations(true#0)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
declare %private function local:inc($c) { $c + 1 };
function-annotations(local:inc#1)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ #Q{http://www.w3.org/2012/xquery}private : () }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $old := %local:deprecated('0.1', '0.2') fn() {}
let $ann := function-annotations($old)
return map:merge($ann)
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  #Q{http://www.w3.org/2005/xquery-local-functions}deprecated :
  ("0.1", "0.2") 
}
</eg></td></tr></tbody></table></def></gitem></glist></div2></div1><div1 id="maps"><head>Processing maps</head><p>Maps were introduced as a new datatype in XDM 3.1. This section describes functions that
         operate on maps.</p><p>A map is a kind of item.</p><p><termdef id="dt-map" term="map">A <term>map</term> 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.</termdef></p><p><termdef id="dt-same-key" term="same key">Within a map, no two entries have the <term>same key</term>. 
            Two atomic items <code nobreak="false">K1</code> and <code nobreak="false">K2</code> are the <term>same key</term>
            for this purpose if the <phrase diff="chg" at="2023-01-25">function call <code nobreak="false">fn:atomic-equal($K1, $K2)</code></phrase>
            returns <code nobreak="false">true</code>.</termdef></p><p>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).</p><p>Maps are immutable, and have no identity separate from their content. 
            For example, the <function>map:remove</function> 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 <function>map:remove</function> with the same arguments return maps that are
            indistinguishable from each other; there is no way of asking whether these are “the same map”.</p><p>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 
            <code nobreak="false">function($key as xs:anyAtomicValue) as item()*</code>. Calling the function has the same effect as calling
            the <function>map:get</function> function: the expression
            <code nobreak="false">$map($key)</code> returns the same result as <code nobreak="false">get($map, $key)</code>. For example, if <code nobreak="false">$books-by-isbn</code>
            is a map whose keys are ISBNs and whose assocated values are <code nobreak="false">book</code> elements, then the expression
            <code nobreak="false">$books-by-isbn("0470192747")</code> returns the <code nobreak="false">book</code> 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.</p><div2 id="map-ordering"><head>Ordering of Maps</head><changes><change issue="1651" PR="1703" date="2025-01-14">Ordered maps are introduced.</change></changes><p>In 4.0, the entries in a map are ordered. The <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref> of a map
            is referred to as <term>entry order</term>.</p><p>The entry order of the entries in a map is defined by the function or expression
               that creates the map, and affects the result of functions and expressions
               that process multiple entries in a map, for example the function <function>map:keys</function>
               and the expression 
               <code nobreak="false">for key $k value $v return <var>EXPR</var></code>. The ordering
               is also reflected in the output
            of the <code nobreak="false">json</code> and <code nobreak="false">adaptive</code> serialization methods.</p><note><p>Order is maintained in maps for two main reasons:</p><ulist><item><p>To make the representation of a map (such as its JSON
                     serialization) easier for human readers to process: for example when
                  visually inspecting the result of a JSON transformation;</p></item><item><p>To make the result of different implementations interoperable.</p></item></ulist><p>Although it is possible to use the ordering of a map to capture
               semantic information, the design of functions such as <function>fn:deep-equal</function>
               discourages this: maps are compared with each other, and matched against map types,
               without regard to the order of entries.</p></note></div2><div2 id="map-composition-decomposition" diff="add" at="2023-04-19"><head>Composing and Decomposing Maps</head><p>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.</p><p>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:</p><olist><item><p>A map can be represented as a sequence of single-entry maps.</p><p><termdef id="dt-single-entry-map" term="single-entry map">A <term>single-entry map</term> is a map containing a single
               entry.</termdef></p><p>It is possible to decompose any map into a sequence of <termref def="dt-single-entry-map">single-entry maps</termref>,
                  and to construct a map from a sequence of single-entry maps.</p><p>For example the map
               <code nobreak="false">{ "x": 1, "y": 2 }</code> can be decomposed to the sequence <code nobreak="false">({ "x": 1 }, { "y": 2 })</code>.</p></item><item><p>A map can be represented as a sequence of JNodes.</p><p>A JNode holds the map key in its <term>·jkey·</term> property and the corresponding
            value in its <term>·jvalue·</term> property.</p></item></olist><p diff="add" at="2023-04-03">The following table summarizes the way in which these two representations 
            can be used to compose and decompose maps:</p><table role="data" diff="add" at="2023-04-03"><thead><tr><th rowspan="1" colspan="1">Operation</th><th rowspan="1" colspan="1">Single-Entry Maps</th><th rowspan="1" colspan="1">JNodes</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p>Decompose a map</p></td><td rowspan="1" colspan="1"><p><code nobreak="false">map:entries($map)</code></p></td><td rowspan="1" colspan="1"><p><code nobreak="false">$map/child::*</code></p></td></tr><tr><td rowspan="1" colspan="1"><p>Compose a map</p></td><td rowspan="1" colspan="1"><p><code nobreak="false">map:merge($entries)</code></p></td><td rowspan="1" colspan="1"><p><code nobreak="false">map:build($jnodes, jkey#1, jvalue#1)</code></p></td></tr><tr><td rowspan="1" colspan="1"><p>Create a single entry</p></td><td rowspan="1" colspan="1"><p><code nobreak="false">map:entry($key, $value)</code></p></td><td rowspan="1" colspan="1"><p><code nobreak="false">{$key : $value}/child::*</code></p></td></tr><tr><td rowspan="1" colspan="1"><p>Extract the key part of a single entry</p></td><td rowspan="1" colspan="1"><p><code nobreak="false">map:keys($entry)</code></p></td><td rowspan="1" colspan="1"><p><code nobreak="false">jkey($jnode)</code></p></td></tr><tr><td rowspan="1" colspan="1"><p>Extract the value part of a single entry</p></td><td rowspan="1" colspan="1"><p><code nobreak="false">map:items($entry)</code></p></td><td rowspan="1" colspan="1"><p><code nobreak="false">jvalue($jnode)</code></p></td></tr></tbody></table><p>It is also possible to decompose a map using:</p><ulist><item><p>The function <function>map:for-each</function></p></item><item><p>The expression <code nobreak="false">for key $k value $v in $map return ....</code></p></item></ulist><example><head>Reordering the entries in a map</head><p>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.</p><olist><item><p>Using <code nobreak="false">map:entries</code> and <code nobreak="false">map:merge</code>:</p><eg xml:space="preserve">map:entries($map) =&gt; sort-by({'key': map:keys#1}) =&gt; map:merge()</eg></item><item><p>Using JNodes:</p><eg xml:space="preserve">$map/* =&gt; sort-by({'key': jkey#1}) =&gt; map:build(jkey#1, jvalue#1)</eg></item><item><p>Using <code nobreak="false">map:for-each</code>:</p><eg xml:space="preserve">map:merge( map:for-each($map, map:entry#2) =&gt; sort-by({'key': map:keys#1}) )</eg></item><item><p>Using an XQuery FLWOR expression:</p><eg xml:space="preserve">map:merge( for key $k value $v order by $k return {$k : $v} )</eg></item></olist></example></div2><div2 id="formal-specification-of-maps"><head>Formal specification of maps</head><p>The XDM data model (<bibref ref="xpath-datamodel-40"/>) defines three primitive operations on maps:</p><ulist><item><p><code nobreak="false">dm:empty-map</code> constructs the empty map.</p></item><item><p><code nobreak="false">dm:map-put</code> adds or replaces an entry in a map.</p></item><item><p><code nobreak="false">dm:iterate-map</code> applies a supplied function to every entry in a map.</p></item></ulist><p>The functions in this section are all specified by means of equivalent expressions that either call
            these primitives directly, or invoke other functions that rely on these primitives. The specifications
            avoid relying on XPath language constructs that manipulate maps, such as map constructor syntax, lookup
            expressions, or FLWOR expressions. This is done to allow these language constructs
            to be specified by reference to this function library, without risk of circularity.</p><p>There is one exception to this rule: for convenience, the notation <code nobreak="false">{}</code> is used to represent
            the empty map, in preference to a call on <code nobreak="false">dm:empty-map()</code>.</p><p>The formal equivalents are not intended to provide a realistic way of implementating the
            functions (in particular, any real implementation might be expected to implement <function>map:get</function>
            and <function>map:put</function> much more efficiently). They do, however, provide a framework that allows
            the correctness of a practical implementation to be verified.</p><ednote><edtext>TODO: as yet there is no formal equivalent for <code nobreak="false">map:find()</code>.</edtext></ednote></div2><div2 id="map-functions"><head>Functions that operate on maps</head><p>The functions defined in this section use a conventional namespace prefix <code nobreak="false">map</code>, which
               is assumed to be bound to the namespace URI <code nobreak="false">http://www.w3.org/2005/xpath-functions/map</code>.</p><p>The function call <code nobreak="false">map:get($map, $key)</code> can be used to retrieve the value associated with a given key.</p><p>There is no operation to atomize a map or convert it to a string. The function <function>fn:serialize</function> can in some cases
            be used to produce a JSON representation of a map.</p><p>Note that when the required type of an argument to a function such as <function>map:build</function>
            is a map type, then the coercion rules ensure that a JNode can be supplied in the function call:
            if the <term>·jvalue·</term> property of the JNode is a map, then the map is automatically
            extracted as if by the <function>jvalue</function> function.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:build</code></td><td rowspan="1" colspan="1">Returns a map that typically contains one entry for each item in a supplied input sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:contains</code></td><td rowspan="1" colspan="1">Tests whether a supplied map contains an entry for a given key.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:empty</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the supplied map contains no entries.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:entries</code></td><td rowspan="1" colspan="1">Returns a sequence containing all the key-value pairs present in a map, each represented
            as a <termref def="dt-single-entry-map"/>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:entry</code></td><td rowspan="1" colspan="1"><phrase>Returns</phrase> a <termref def="dt-single-entry-map"/> that 
            represents a single key-value pair.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:filter</code></td><td rowspan="1" colspan="1">Selects entries from a map, returning a new map.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:find</code></td><td rowspan="1" colspan="1">Searches the supplied input sequence and any contained maps and arrays for a map entry with the supplied key,
            and returns the corresponding values.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:for-each</code></td><td rowspan="1" colspan="1">Applies a supplied function to every entry in a map, returning the 
            <xtermref spec="XP40" ref="dt-sequence-concatenation">sequence concatenation</xtermref> of the results.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:get</code></td><td rowspan="1" colspan="1">Returns the value associated with a supplied key in a given map.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:items</code></td><td rowspan="1" colspan="1">Returns a sequence containing all the values present in a map, in order.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:keys</code></td><td rowspan="1" colspan="1">Returns a sequence containing all the keys present in a map.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:keys-where</code></td><td rowspan="1" colspan="1">Returns a sequence containing selected keys present in a map.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:merge</code></td><td rowspan="1" colspan="1">Returns a map that combines the entries from a number of existing maps.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:put</code></td><td rowspan="1" colspan="1">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.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:remove</code></td><td rowspan="1" colspan="1">Returns a map containing all the entries from a supplied map, except <phrase>those having a specified key</phrase>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">map:size</code></td><td rowspan="1" colspan="1">Returns the number of entries in the supplied map.</td></tr></tbody></table><div3 id="func-map-build" diff="add" at="A"><head>map:build</head><changes><change issue="151" PR="203" date="2022-10-18">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a map that typically contains one entry for each item in a supplied input sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="build" return-type="map(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="key" type="(fn($item as item(), $position as xs:integer) as xs:anyAtomicType*)?" default="fn:identity#1" note="default-on-empty"/><arg name="value" type="(fn($item as item(), $position as xs:integer) as item()*)?" default="fn:identity#1" note="default-on-empty"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function processes each item in <code nobreak="false">$input</code> in order.
            It calls the <code nobreak="false">$key</code> function on that item to obtain a sequence of key values,
            and the <code nobreak="false">$value</code> function to obtain an associated value.
            Then, for each key value:</p><ulist><item><p>If the key is not already present in the target map, the processor adds a
               new key-value pair to the map, with that key and that value. </p></item><item><p>If the key is already present, the processor combines the new value for the key
               with the existing value; the way they are combined is determined by the 
               <code nobreak="false">duplicates</code> option.</p><p>By default, when two duplicate entries occur:</p><ulist><item><p>A single combined entry will be present in the result.</p></item><item><p>This entry will contain the 
                     <xtermref spec="XP40" ref="dt-sequence-concatenation">sequence concatenation</xtermref>
                  of the supplied values.</p></item><item><p>The position of the combined entry in the
                  <xtermref spec="DM40" ref="dt-entry-order"/> of the result map
                  will correspond to the position of the first of the duplicates.</p></item><item><p>The key of the combined entry 
                  will correspond to the key of one of the duplicates: it is
                  <termref def="implementation-dependent"/> which one is chosen.
                  (It is possible for two keys to be considered duplicates even if they differ:
                  for example, they may have different type annotations, or they may
                  be <code nobreak="false">xs:dateTime</code> values in different timezones.) </p></item></ulist><p>The <code nobreak="false">$options</code> argument can be used to control the 
            way in which duplicate keys are handled. 
            The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.
            The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="duplicates" type="(enum( &#34;reject&#34;, &#34;use-first&#34;, &#34;use-last&#34;, &#34;use-any&#34;, &#34;combine&#34;) | fn(item()*, item()*) as item()*)?" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="7" colspan="1"><p><code nobreak="false">duplicates?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines the policy for handling duplicate keys: specifically, the action to be
                  taken if two entries in the input sequence have key values
                  <var>K1</var> and <var>K2</var> where <var>K1</var> and <var>K2</var> are the 
                  <termref def="dt-same-key">same key</termref>. 
               <ulist><item><p><term>Type: </term><code nobreak="false">(enum( "reject", "use-first", "use-last", "use-any", "combine") | fn(item()*, item()*) as item()*)?</code></p></item><item><p><term>Default: </term><code nobreak="false">"combine"</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">"reject"</code></td><td rowspan="1" colspan="1">
                     Equivalent to supplying a function that raises a dynamic error
                     with error code "FOJS0003". The effect is that duplicate keys
                     result in an error.
                  </td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">"use-first"</code></td><td rowspan="1" colspan="1">Equivalent to supplying the function <code nobreak="false">fn($a, $b){ $a }</code>.
                     The effect is that the first of the duplicates is chosen.
                  </td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">"use-last"</code></td><td rowspan="1" colspan="1">Equivalent to supplying the function <code nobreak="false">fn($a, $b){ $b }</code>.
                     The effect is that the last of the duplicates is chosen.
                  </td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">"use-any"</code></td><td rowspan="1" colspan="1">Equivalent to supplying the function <code nobreak="false">fn($a, $b){ one-of($a, $b) }</code>
                     where <code nobreak="false">one-of</code> chooses either <code nobreak="false">$a</code> or <code nobreak="false">$b</code> in
                     an <termref def="implementation-dependent"/> way. The effect is that it is
                     <termref def="implementation-dependent"/> which of the duplicates is chosen.
                  </td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">"combine"</code></td><td rowspan="1" colspan="1">Equivalent to supplying the function <code nobreak="false">fn($a, $b){ $a, $b }</code>
                     (or equivalently, the function <code nobreak="false">op(",")</code>).
                     The effect is that the result contains the <xtermref spec="XP40" ref="dt-sequence-concatenation"/>
                     of the values having the same key, retaining order.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">function(*)</code></td><td rowspan="1" colspan="1">
                     A function with signature <code nobreak="false">fn(item()*, item()*) as item()*</code>.
                     The function is called for any entry in the input sequence that has the 
                     <termref def="dt-same-key"/> as a previous entry. The first argument
                     is the existing value associated with the key; the second argument
                     is the value associated with the key in the duplicate input entry,
                     and the result is the new value to be associated with the key. The effect
                     is cumulative: for example if there are three values <var>X</var>, <var>Y</var>,
                     and <var>Z</var> associated with the same key, and the supplied function is
                     <var>F</var>, then the result is an entry whose value is 
                     <code nobreak="false"><var>X</var> =&gt; <var>F</var>(<var>Y</var>) =&gt; <var>F</var>(<var>Z</var>)</code>.
                  </td></tr></tbody></table></item></ulist></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">for-each(
  $input, 
  fn($item, $pos) {
    for-each($key($item, $pos), fn($k) {
      map:entry($k, $value($item, $pos))
    }
  )}
)
=&gt; map:merge($options)</eg></def></gitem><gitem><label>Error Conditions</label><def><p>An error is raised <errorref spec="FO" class="JS" code="0003"/> if the value of 
          <code nobreak="false">$options</code> indicates that duplicates are to be rejected, and a duplicate key is encountered.</p><p>An error is raised <errorref spec="FO" class="JS" code="0005"/> if the value of 
          <code nobreak="false">$options</code> includes an entry whose key is defined 
          in this specification, and whose value is not a permitted value for that key.</p></def></gitem><gitem><label>Notes</label><def><note><p>The default function for both <code nobreak="false">$key</code> and <code nobreak="false">$value</code> is the identity function.
            Although it is permitted to default both, this serves little purpose: usually at least one of these arguments
            will be supplied.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:build((), string#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{}</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:build(1 to 10, fn { . mod 3 })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ 0: (3, 6, 9), 1: (1, 4, 7, 10), 2: (2, 5, 8) }</code></p><p><emph>(Returns a map with one entry for each distinct value of <code nobreak="false">. mod 3</code>. The
                  function to compute the value is the identity function, and duplicates are combined by
                  sequence concatenation.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(
  1 to 5,
  value := format-integer(?, "w")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 1: "one", 2: "two", 3: "three", 4: "four", 5: "five" }</eg><p><emph>(Returns a map with five entries. The function to compute the key is an identity function, the
                  function to compute the value invokes <function>fn:format-integer</function>.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(
  ("January", "February", "March", "April", "May", "June",
   "July", "August", "September", "October", "November", "December"),
  substring(?, 1, 1)
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "A": ("April", "August"),
  "D": ("December"),
  "F": ("February"),
  "J": ("January", "June", "July"),
  "M": ("March", "May"),
  "N": ("November"),
  "O": ("October"),
  "S": ("September")
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(1 to 5, {
  1: ("eins", "one"),
  4: ("vier", "four")
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "eins": 1,
  "one": 1,
  "vier": 4,
  "four": 4
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(
  ("apple", "apricot", "banana", "blueberry", "cherry"), 
  substring(?, 1, 1),
  string-length#1,
  { "duplicates": op("+") }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "a": 12, "b": 15, "c": 6 }</eg><p><emph>(Constructs a map where the key is the first character of an input item, and where the corresponding value
                  is the total string-length of the items starting with that character.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(
  ('Wang', 'Liu', 'Zhao'),
  key := fn($name, $pos) { $name },
  value := fn($name, $pos) { $pos }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "Wang": 1, "Liu": 2, "Zhao": 3 }</eg><p><emph>(Returns an inverted index for the input sequence with the 
                  string stored as key and the position stored as value.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $titles := &lt;titles&gt;
  &lt;title&gt;A Beginner’s Guide to &lt;ix&gt;Java&lt;/ix&gt;&lt;/title&gt;
  &lt;title&gt;Learning &lt;ix&gt;XML&lt;/ix&gt;&lt;/title&gt;
  &lt;title&gt;Using &lt;ix&gt;XML&lt;/ix&gt; with &lt;ix&gt;Java&lt;/ix&gt;&lt;/title&gt;
&lt;/titles&gt;
return map:build($titles/title, fn($title) { $title/ix })
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "Java": (
    &lt;title&gt;A Beginner’s Guide to &lt;ix&gt;Java&lt;/ix&gt;&lt;/title&gt;,
    &lt;title&gt;Using &lt;ix&gt;XML&lt;/ix&gt; with &lt;ix&gt;Java&lt;/ix&gt;&lt;/title&gt;
  ),
  "XML": (
    &lt;title&gt;Learning &lt;ix&gt;XML&lt;/ix&gt;&lt;/title&gt;,
    &lt;title&gt;Using &lt;ix&gt;XML&lt;/ix&gt; with &lt;ix&gt;Java&lt;/ix&gt;&lt;/title&gt;
  )
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(//employee, fn { @ssn })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>A map whose keys are employee <code nobreak="false">@ssn</code> values, and whose
               corresponding values are the employee nodes</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(//employee, fn { @location }, fn { 1 }, { "duplicates": op("+") })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>A map whose keys are employee <code nobreak="false">@location</code> values, and whose
               corresponding values represent the number of employees at each distinct location. Any employees that
               lack an <code nobreak="false">@location</code> attribute will be excluded from the result.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(
  //employee,
  key := fn { @location }, 
  options := { "duplicates": fn($a, $b) { highest(($a, $b), (), fn { xs:decimal(@salary) }) } }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>A map whose keys are employee <code nobreak="false">@location</code> values, and whose
               corresponding values contain the employee node for the highest-paid employee at each distinct location</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:build(//*, generate-id#1)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>A map allowing efficient access to every element in a document by means
               of its <function>fn:generate-id</function> value.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $tree := parse-json('{
  "type": "package",
  "name": "org",
  "content": [
      { "type": "package",
        "name": "xml",
        "content": [
            { "type": "package",
              "name": "sax",
              "content": [
                  { "type": "class",
                    "name": "Attributes"},
                  { "type": "class",
                    "name": "ContentHandler"},
                  { "type": "class",
                    "name": "XMLReader"}
               ]
            }]
       }]
   }')
   return map:build($tree/descendant-or-self::jnode(*, record(type, name, content?)),
                    fn{./ancestor-or-self::jnode()?name =&gt; string-join(".")},
                    fn{`{?type} {?name}`})
            </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "org":"package org",
  "org.xml":"package xml",
  "org.xml.sax":"package sax",
  "org.xml.sax.Attributes": "class Attributes",
  "org.xml.sax.ContentHandler": "class ContentHandler",
  "org.xml.sax.XMLReader": "class XMLReader" }</eg><p><emph>(Constructs a map allowing efficient access to values in a recursive JSON structure
               using hierarchic paths).</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-contains"><head>map:contains</head><glist><gitem><label>Summary</label><def><p>Tests whether a supplied map contains an entry for a given key.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="contains" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/><arg name="key" type="xs:anyAtomicType"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:contains</function> returns <code nobreak="false">true</code> if the <termref def="dt-map">map</termref> supplied as <code nobreak="false">$map</code> contains an entry with the <termref def="dt-same-key">same key</termref> as <code nobreak="false">$key</code>; otherwise it returns <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">some(map:keys($map), atomic-equal(?, $key))</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $week := {
  0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag"
}</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:contains($week, 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:contains($week, 9)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:contains({}, "xyz")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:contains({ "xyz": 23 }, "xyz")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:contains({ "abc": 23, "xyz": () }, "xyz")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-empty"><head>map:empty</head><changes><change issue="827 843" PR="969" date="2023-11-18">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the supplied map contains no entries.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="empty" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns <code nobreak="false">true</code> if and only if <code nobreak="false">$map</code> contains no
            entries, that is, if <code nobreak="false">map:size($map) eq 0</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">map:size($map) eq 0</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:empty({})</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:empty({ 1: () })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-entries" diff="add" at="2023-04-19"><head>map:entries</head><changes><change issue="29 314" PR="360" date="2023-03-21">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a sequence containing all the key-value pairs present in a map, each represented
            as a <termref def="dt-single-entry-map"/>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="entries" return-type="map(*)*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:entries</function> takes any <termref def="dt-map">map</termref>
            as its <code nobreak="false">$map</code> argument and returns the key-value pairs that are present in the map as
            a sequence of <termref def="dt-single-entry-map">single-entry maps</termref>, in 
            <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">map:for-each($map, map:entry#2)</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:entries(
  { 1: "yes", 0: "no" }
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">({ 1: "yes" }, { 0: "no" })</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-entry"><head>map:entry</head><glist><gitem><label>Summary</label><def><p><phrase>Returns</phrase> a <termref def="dt-single-entry-map"/> that 
            represents a single key-value pair.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="entry" return-type="map(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="key" type="xs:anyAtomicType"/><arg name="value" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:entry</function> returns a <termref def="dt-map">map</termref> which  contains a single
            entry. The key of the entry in the new map is
               <code nobreak="false">$key</code>, and its associated value is <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">map:put({}, $key, $value)</eg></def></gitem><gitem><label>Notes</label><def><note><p>The function <function>map:entry</function> is intended primarily for use in conjunction with
            the function <function>map:merge</function>. For example, a map containing seven entries may be
            constructed like this:</p><eg xml:space="preserve">
map:merge((
  map:entry("Su", "Sunday"),
  map:entry("Mo", "Monday"),
  map:entry("Tu", "Tuesday"),
  map:entry("We", "Wednesday"),
  map:entry("Th", "Thursday"),
  map:entry("Fr", "Friday"),
  map:entry("Sa", "Saturday")
))</eg><p>The <function>map:merge</function> function can be used to construct
            a map with a variable number of entries, for example:</p><eg xml:space="preserve">
map:merge(//book ! map:entry(isbn, .))</eg></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:entry("M", "Monday")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "M": "Monday" }</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-filter" diff="add" at="A"><head>map:filter</head><changes><change issue="584 843 1074 1133" PR="969 1134" date="2023-07-11">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change><change issue="1651" PR="1703" date="2025-01-14">Enhanced to allow for ordered maps.</change><change issue="1718" PR="2224" date="2025-10-02">The <code nobreak="false">$action</code> callback function now accepts an optional position argument.</change></changes><glist><gitem><label>Summary</label><def><p>Selects entries from a map, returning a new map.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="filter" return-type="map(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/><arg name="predicate" type="fn($key as xs:anyAtomicType, $value as item()*, $position as xs:integer) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:filter</function> takes any <termref def="dt-map">map</termref> as its <code nobreak="false">$map</code> argument and applies the supplied function
            to each entry in the map; the result is a new map containing those entries for which
            the function returns <code nobreak="false">true</code>. A return value of <code nobreak="false">()</code> from the
         predicate is treated as <code nobreak="false">false</code>.</p><p>The function supplied as <code nobreak="false">$predicate</code> takes three arguments. It is called
            supplying the key of the map entry as the first argument, the associated value as
            the second argument, and the 1-based integer position as the third argument.</p><p>The relative <xtermref spec="DM40" ref="dt-entry-order">order of entries</xtermref> 
            in the returned map is the same as their relative order in <code nobreak="false">$map</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">map:for-each($map, fn($key, $value, $position) {
  if ($predicate($key, $value, $position)) {
    map:entry($key, $value)
  }
})
=&gt; map:merge()</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:filter(
  { 1: "Sunday", 2: "Monday", 3: "Tuesday", 4: "Wednesday",
    5: "Thursday", 6: "Friday", 7: "Saturday" },
  fn($k, $v) { $k = (1, 7) }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 1: "Sunday", 7: "Saturday" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:filter(
  { 1: "Sunday", 2: "Monday", 3: "Tuesday", 4: "Wednesday",
    5: "Thursday", 6: "Friday", 7: "Saturday" },
  fn($k, $v) { $v = ("Saturday", "Sunday") }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 1: "Sunday", 7: "Saturday" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $en-ja := { 'one': '一', 'two': '二', 'three': '三' }
return map:filter($en-ja, fn($en, $ja, $pos) {
  $pos mod 2 = 1
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 'one': '一', 'three': '三' }</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-find"><head>map:find</head><changes><change issue="1651" PR="1703" date="2025-01-14">Enhanced to allow for ordered maps.</change></changes><glist><gitem><label>Summary</label><def><p>Searches the supplied input sequence and any contained maps and arrays for a map entry with the supplied key,
            and returns the corresponding values.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="find" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="key" type="xs:anyAtomicType"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:find</function> searches the sequence supplied as <code nobreak="false">$input</code>
         looking for map entries whose key is the <termref def="dt-same-key">same key</termref>
         as <code nobreak="false">$key</code>. The associated value in any such map entry (each being in general a sequence)
         is returned as a member of the result array.</p><p>The search processes the <code nobreak="false">$input</code> sequence using the following recursively defined rules 
            (any equivalent algorithm may be used provided it delivers
            the same result, respecting those rules that constrain the order of the result):</p><olist><item><p>To process a sequence, process each of its items in order.</p></item><item><p>To process an item that is an array, process each of its members in order 
               (each member is, in general, a sequence).</p></item><item><p>To process an item that is a map, then for each key-value entry (<var>K</var>, <var>V</var>)
               in the map (in <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>)
               perform both of the following steps, in order:</p><olist><item><p>If <var>K</var> is the <termref def="dt-same-key">same key</termref> as <code nobreak="false">$key</code>, 
                  then add <var>V</var> as a new member to the end of the result array.</p></item><item><p>Process <var>V</var> (which is, in general, a sequence).</p></item></olist></item><item><p>To process an item that is neither a map nor an array, do nothing. (Such items are ignored).</p></item></olist></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$input</code> is the empty sequence, map, or array, or if the requested <code nobreak="false">$key</code> is not found,
            the result will be a zero-length array.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $responses := [
  { 0: 'no', 1: 'yes' },
  { 0: 'non', 1: 'oui' },
  { 0: 'nein', 1: ('ja', 'doch') }
]</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $inventory := {
  "name": "car",
  "id": "QZ123", 
  "parts": [ { "name": "engine", "id": "YW678", "parts": [] } ]
}</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:find($responses, 0)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 'no', 'non', 'nein' ]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:find($responses, 1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 'yes', 'oui', ('ja', 'doch') ]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:find($responses, 2)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:find($inventory, "parts")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[
  [ { "name": "engine", "id": "YW678", "parts": [] } ],
  []
]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-for-each"><head>map:for-each</head><changes><change issue="1651" PR="1703" date="2025-01-14">Enhanced to allow for ordered maps.</change><change issue="1718" PR="2224" date="2025-10-02">The <code nobreak="false">$action</code> callback function now accepts an optional position argument.</change></changes><glist><gitem><label>Summary</label><def><p>Applies a supplied function to every entry in a map, returning the 
            <xtermref spec="XP40" ref="dt-sequence-concatenation">sequence concatenation</xtermref> of the results.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="for-each" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/><arg name="action" type="fn($key as xs:anyAtomicType, $value as item()*, $position as xs:integer) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:for-each</function> takes any <termref def="dt-map">map</termref> as its <code nobreak="false">$map</code> argument and applies the supplied function
            to each entry in the map, in <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>; 
            the result is the <xtermref spec="XP40" ref="dt-sequence-concatenation"/> 
            of the results of these function calls.</p><p>The function supplied as <code nobreak="false">$action</code> takes three arguments. It is called
            supplying the key of the map entry as the first argument, the associated value as
            the second argument, and the 1-based integer position as the third argument.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function is defined as follows, making use of primitive constructors and accessors defined
		in <bibref ref="xpath-datamodel-40"/>.</p><eg xml:space="preserve">dm:iterate-map($map, $action, $position)</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:for-each(
  { 1: "yes", 2: "no" },
  fn($k, $v) { $k }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">(1, 2)</eg><p><emph>(This function call is equivalent to calling <code nobreak="false">map:keys</code>.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">distinct-values(
  map:for-each(
    { 1: "yes", 2: "no" },
    fn($k, $v) { $v }
  )
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">("yes", "no")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge(
  map:for-each(
    { "a": 1, "b": 2 },
    fn($k, $v) { map:entry($k, $v + 1) }
  )
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "a": 2, "b": 3 }</eg><p><emph>(This function call returns a map with the same keys as the input map,
                  with the value of each entry increased by one.)</emph></p></td></tr><tr><td colspan="2" rowspan="1"><p>This XQuery example converts the entries in a map to attributes on a newly constructed
                  element node:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">
let $dimensions := { 'height': 3, 'width': 4, 'depth': 5 }
return &lt;box&gt;{
  map:for-each($dimensions, fn($k, $v) { attribute { $k } { $v } })
}&lt;/box&gt;</eg></td></tr><tr><td colspan="2" rowspan="1"><p>The result is the element <code nobreak="false">&lt;box height="3" width="4"
                  depth="5"/&gt;</code>.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $en-ja := { 'one': '一', 'two': '二', 'three': '三' }
return map:for-each($en-ja, fn($en, $ja, $pos) {
  $pos || '. ' || $en || ': ' || $ja
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"1. one: 一", "2. two: 二", "3. three: 三"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-get"><head>map:get</head><changes><change issue="1363" PR="289 1901" date="2025-04-15">A third argument is added, allowing user control of how absent keys should be handled.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the value associated with a supplied key in a given map.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="get" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/><arg name="key" type="xs:anyAtomicType"/><arg name="default" type="item()*" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:get</function> attempts to find an entry within the <termref def="dt-map">map</termref> supplied as <code nobreak="false">$map</code> that has 
            the <termref def="dt-same-key">same key</termref> as <code nobreak="false">$key</code>. If there is such an entry, it returns the associated value;
            if not, it returns the supplied <code nobreak="false">$default</code> value.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function is defined as follows, making use of primitive constructors and accessors defined
		in <bibref ref="xpath-datamodel-40"/>.</p><eg xml:space="preserve">let $entry := dm:iterate-map($map, fn($k, $v) {
  if (atomic-equal($k, $key)) {
    map:entry($k, $v)
  }
})
return (
  if (exists($entry))
  then map:items($entry)
  else $default
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>A return value of <code nobreak="false">()</code> from <function>map:get#2</function> could indicate that
            the key is present in the map with an associated value of <code nobreak="false">()</code>, or it could
            indicate that the key is not present in the map. The two cases can be distinguished by
            either by calling <function>map:contains</function> to test whether an entry is present, or by using
            a <code nobreak="false">$default</code> value to return a value known never to appear in the map.</p><p>Invoking the <termref def="dt-map">map</termref> as a function item has the same effect
            as calling <code nobreak="false">get</code> with no <code nobreak="false">$default</code>
            argument: that is, when <code nobreak="false">$map</code> is a map, the expression
               <code nobreak="false">$map($K)</code> is equivalent to <code nobreak="false">map:get($map, $K)</code>. Similarly, the
            expression <code nobreak="false">map:get(map:get(map:get($map, 'employee'), 'name'), 'first')</code> can
            be written as <code nobreak="false">$map('employee')('name')('first')</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $week := {
  0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag"
}</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:get($week, 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"Donnerstag"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:get($week, 9)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p><p><emph>(When the key is not present, the function returns the empty
                  sequence.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:get(map:entry(7,()), 7)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p><p><emph>(An empty sequence as the result can also signify that the key is
                  present and the associated value is the empty sequence.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:get($week, 7, "n/a")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"n/a"</code></p><p><emph>(The third argument supplies a default value.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-items" diff="add" at="2023-04-19"><head>map:items</head><changes><change issue="1672" PR="1687" date="2025-01-14">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a sequence containing all the values present in a map, in order.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="items" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:items</function> takes any <termref def="dt-map">map</termref>
            as its <code nobreak="false">$map</code> argument and returns the values that are present in the map as
            a sequence, in <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>.</p><p>The effect of the function is equivalent to <code nobreak="false">$map?*</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">map:for-each($map, fn($key, $value) { $value })</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:items({ 1: "yes", 2: "no" })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">("yes", "no")</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:items({
  1: ("red", "green"),
  2: ("blue", "yellow"),
  3: ()
})</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">("red", "green", "blue", "yellow")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-keys"><head>map:keys</head><glist><gitem><label>Summary</label><def><p>Returns a sequence containing all the keys present in a map.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="keys" return-type="xs:anyAtomicType*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function <function>map:keys</function> takes any
            <termref def="dt-map">map</termref> as its <code nobreak="false">$map</code> argument and returns
            the keys that are present in the map as a sequence of atomic items, 
            in <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">map:for-each($map, fn($key, $value) { $key })</eg></def></gitem><gitem><label>Notes</label><def><note><p>The number of items in the result will be the same as the number of entries in the map,
            and the result sequence will contain no duplicate values.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:keys({ 1: "yes", 0: "no" })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">(1, 0)</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">({ "red": 0}, { "blue": 1}, { "green": 2 })
=&gt; map:merge()
=&gt; map:keys()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">("red", "blue", "green")</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-keys-where"><head>map:keys-where</head><changes><change issue="467 504" PR="478 515" date="2023-05-16">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Returns a sequence containing selected keys present in a map.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="keys-where" return-type="xs:anyAtomicType*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/><arg name="predicate" type="fn($key as xs:anyAtomicType, $value as item()*) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function <function>map:keys</function> takes any
            <termref def="dt-map">map</termref> as its <code nobreak="false">$map</code> argument. The
            <code nobreak="false">$predicate</code> function takes the key and the value of the corresponding
            map entry as an argument, and the result is a sequence containing the keys of those
            entries for which the predicate function returns <code nobreak="false">true</code>, in 
            <xtermref spec="DM40" ref="dt-entry-order">entry order</xtermref>.</p><p>A return value of <code nobreak="false">()</code> from the predicate function is 
            treated as <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">map:for-each($map, fn($key, $value) {
  if ($predicate($key, $value)) { $key }
})</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $numbers := {
  0: "zero",
  1: "one",
  2: "two",
  3: "three"
}
return map:keys-where(
  $numbers,
  fn($key, $value) { $value = ("two", "three") }
)
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">(2, 3)</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $square := map:merge(
  (1 to 5) ! map:entry(., . * .)
)
return map:keys-where(
  $square,
  fn($key, $value) { $value &gt; 5 and $value &lt; 20 }
)
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">(3, 4)</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $birthdays := {
  "Agnieszka": xs:date("1980-12-31"),
  "Jabulile": xs:date("2001-05-05"),
  "Joel": xs:date("1969-11-10"),
  "Midori": xs:date("2012-01-08")
}
return map:keys-where($birthdays, fn($name, $date) {
  starts-with($name, "J") and year-from-date($date) = 1969
})
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Joel"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-merge"><head>map:merge</head><changes><change issue="1725" PR="1727" date="2025-01-31">For consistency with the new function <function>map:build</function>, 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 <code nobreak="false">duplicates</code> option.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a map that combines the entries from a number of existing maps.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="merge" return-type="map(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="maps" type="map(*)*"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:merge</function>
            returns a map that is formed by combining the contents of the maps supplied in the <code nobreak="false">$maps</code>
            argument.</p><p>Informally, the supplied maps are combined as follows:</p><olist><item><p>There is one entry in the returned map for each distinct key present in the union
                  of the input maps, where two keys are distinct if they are not the <termref def="dt-same-key">same key</termref>. The order of the input maps,
               and of the entries within these input maps, is retained in the 
               <xtermref spec="DM40" ref="dt-entry-order"/> of the result map.</p></item><item><p>If there are duplicate keys, that is, if two or more maps contain entries having the
                  <termref def="dt-same-key">same key</termref>, then the relevant entries are combined in a way
                   that is controlled by the supplied <code nobreak="false">$options</code>.</p><p>The <code nobreak="false">$options</code> argument takes the same values (with the same meanings)
               as the <function>map:build</function> function, except that the default is different:
               for <code nobreak="false">map:merge</code>, the default for duplicate keys is <code nobreak="false">use-first</code>.</p><note><p>The difference is for backwards compatibility reasons.</p></note><p>With the default options, when duplicate entries occur:</p><olist><item><p>There will be a single entry in the result 
                     corresponding to a set of duplicate entries in the input.
                  </p></item><item><p>The value of that entry will be taken from the first
                  of the duplicates.</p></item><item><p>The position of that entry in the <xtermref spec="DM40" ref="dt-entry-order"/> of the result map will correspond to the
                  position of the first of the duplicates.</p></item><item><p>The key of the combined entry 
                  will correspond to the key of one of the duplicates: it is
                  <termref def="implementation-dependent"/> which one is chosen. (Keys may be 
                  duplicates even though they differ: for example, they may have
                  different type annotations, or they may be <code nobreak="false">xs:dateTime</code>
                  values in different timezones.)</p></item></olist></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>An error is raised <errorref spec="FO" class="JS" code="0003"/> if the value of 
          <code nobreak="false">$options</code> indicates that duplicates are to be rejected, and a duplicate key is encountered.</p><p>An error is raised <errorref spec="FO" class="JS" code="0005"/> if the value of 
          <code nobreak="false">$options</code> includes an entry whose key is defined 
          in this specification, and whose value is not a permitted value for that key.</p></def></gitem><gitem><label>Notes</label><def><note><p>If the input is the empty sequence, the result is the empty map.</p><p>If the input is a sequence of length one, the result map is 
            indistinguishable from the input map.</p><p>There is no requirement that 
            the supplied input maps should have the same or compatible
            types. The type of a map (for example <code nobreak="false">map(xs:integer, xs:string)</code>) is
            descriptive of the entries it currently contains, but is not a constraint on how the map
            may be combined with other maps.</p><p>The XSLT 3.0 recommendation included a specification of this function that incorrectly used
            the option value <code nobreak="false">{ 'duplicates': 'unspecified' }</code> in place of
            <code nobreak="false">{ 'duplicates': 'use-any' }</code>. XSLT implementations wishing to
            preserve backwards compatibility <rfc2119>may</rfc2119> choose to retain support
            for this setting.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $week := {
  0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag"
}</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:merge(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{}</code></p><p><emph>(Returns the empty map).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge((
  map:entry(0, "no"),
  map:entry(1, "yes")
))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "no", 1: "yes" }</eg><p><emph>(Returns a map with two entries).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge(({ "red": 0 }, { "green": 1}, { "blue": 2 })) 
=&gt; map:keys()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"red", "green", "blue"</eg><p><emph>(Note the order of the result.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge(
  ($week, { 7: "Unbekannt" })
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag", 7: "Unbekannt" }</eg><p><emph>(The value of the existing map is unchanged; the <phrase>returned map 
                  contains</phrase> all the entries from <code nobreak="false">$week</code>, supplemented with an additional
                  entry.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge(
  ($week, { 6: "Sonnabend" }),
  { "duplicates": "use-last" }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Sonnabend" }</eg><p><emph>(The value of the existing map is unchanged; the returned map
                  contains all the entries from <code nobreak="false">$week</code>, with one entry replaced by a
                  new entry. Both input maps contain an entry with the key <code nobreak="false">6</code>; the
                  one used in the result is the one that comes last in the input
                  sequence.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge(
  ($week, { 6: "Sonnabend" }),
  { "duplicates": "use-first" }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag" }</eg><p><emph>(The value of the existing map is unchanged; the returned map
                  contains all the entries from <code nobreak="false">$week</code>, with one entry replaced by a
                  new entry. Both input maps contain an entry with the key <code nobreak="false">6</code>; the
                  one used in the result is the one that comes first in the input
                  sequence.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge(
  ($week, { 6: "Sonnabend" }),
  { "duplicates": "combine" }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: ("Samstag", "Sonnabend") }</eg><p><emph>(The value of the existing map is unchanged; the returned map
                  contains all the entries from <code nobreak="false">$week</code>, with one entry replaced by a
                  new entry. Both input maps contain an entry with the key <code nobreak="false">6</code>; the
                  entry that appears in the result is the <xtermref spec="XP40" ref="dt-sequence-concatenation">sequence concatenation</xtermref> of the entries
                  in the input maps, retaining order.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">map:merge(
  ({ "oxygen": 0.22, "hydrogen": 0.68, "nitrogen": 0.1 },
   { "oxygen": 0.24, "hydrogen": 0.70, "nitrogen": 0.06 }), 
  { "duplicates": fn($a, $b) { max(($a, $b)) } })
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "oxygen": 0.24, "hydrogen": 0.70, "nitrogen": 0.1 }</eg><p><emph>(The result map holds, for each distinct key, the maximum of the values
               for that key in the input.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-put"><head>map:put</head><changes><change issue="1651" PR="1703" date="2025-01-14">Enhanced to allow for ordered maps.</change><change issue="1725" PR="1727 1740" date="2025-01-28">It is no longer guaranteed that the new key replaces the existing key.</change></changes><glist><gitem><label>Summary</label><def><p>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.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="put" return-type="map(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/><arg name="key" type="xs:anyAtomicType"/><arg name="value" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$map</code> contains an entry whose key is the <termref def="dt-same-key">same key</termref> as <code nobreak="false">$key</code>, the function returns
         a map in which that entry is replaced (at the same relative position)
         with a new entry whose value is <code nobreak="false">$value</code>. It is 
         <termref def="implementation-dependent"/> whether the key in the new entry
         takes its original value or is replaced by the supplied <code nobreak="false">$key</code>.
         All other entries in the map are unchanged, and retain their relative order.</p><p>Otherwise, when <code nobreak="false">$map</code> contains no such entry, the function
         returns a map containing all entries from the supplied <code nobreak="false">$map</code>
         (retaining their relative position) followed by a new entry whose key
         is <code nobreak="false">$key</code> and whose associated value is <code nobreak="false">$value</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function is defined as follows, making use of primitive constructors and accessors defined
		in <bibref ref="xpath-datamodel-40"/>.</p><eg xml:space="preserve">dm:map-put($map, $key, $value)</eg></def></gitem><gitem><label>Notes</label><def><note><p>There is no requirement that the type of <code nobreak="false">$key</code> and <code nobreak="false">$value</code> be consistent with the types
         of any existing keys and values in the supplied map.</p><p>It is possible to force the new entry to go at the end of the sequence by calling
         <code nobreak="false">map:remove</code> before calling <code nobreak="false">map:put</code>.</p><p>It can happen that the supplied <code nobreak="false">$key</code> is the <termref def="dt-same-key"/>
            as some existing key present in <code nobreak="false">$map</code>, but nevertheless 
            differs from the existing key in some way:
         for example, it might have a different type annotation, or it might be an <code nobreak="false">xs:dateTime</code>
         value in a different timezone. In this situation it is 
         <termref def="implementation-dependent"/> whether the key that appears in the result map
         is the supplied <code nobreak="false">$key</code> or the existing key.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $week := {
  0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag"
}</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:put($week, 6, "Sonnabend")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Sonnabend" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:put($week, -1, "Unbekannt")</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag", -1: "Unbekannt" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json('{ "red": 0, "green": 1, "blue": 2 }')
=&gt; map:put("yellow", -1) 
=&gt; map:keys()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"red", "green", "blue", "yellow"</eg><p><emph>(The new entry is added at the end of the list.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json('{ "red": 0, "green": 1, "blue": 2 }')
=&gt; map:put("red", -1) 
=&gt; map:keys()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"red", "green", "blue"</eg><p><emph>(Changing the value for an existing key does not 
                  change the order of the keys.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-remove"><head>map:remove</head><changes><change issue="1651" PR="1703" date="2025-01-14">Enhanced to allow for ordered maps.</change></changes><glist><gitem><label>Summary</label><def><p>Returns a map containing all the entries from a supplied map, except <phrase>those having a specified key</phrase>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="remove" return-type="map(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/><arg name="keys" type="xs:anyAtomicType*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:remove</function> returns a <termref def="dt-map">map</termref> containing all the entries in <code nobreak="false">$map</code> except for any entry whose key is 
            the <termref def="dt-same-key">same key</termref> as <phrase>an item in</phrase>
            <code nobreak="false">$keys</code>.</p><p>No failure occurs <phrase>if an item in <code nobreak="false">$keys</code> does not correspond to any entry in <code nobreak="false">$map</code>;
            that key value is simply ignored</phrase>.</p><p>The relative position of retained entries in the result map 
            is the same as their relative position in <code nobreak="false">$map</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">map:filter(
  $map,
  fn($k, $v) { not(some($keys, atomic-equal($k, ?))) }
)</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $week := {
  0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag"
}</eg></td></tr></tbody></table><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:remove($week, 4)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  5: "Freitag", 6: "Samstag" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:remove($week, 23)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:remove($week, (0, 6 to 7))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 1: "Montag", 2: "Dienstag", 3: "Mittwoch", 4: "Donnerstag",
  5: "Freitag" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">map:remove($week, ())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ 0: "Sonntag", 1: "Montag", 2: "Dienstag", 3: "Mittwoch",
  4: "Donnerstag", 5: "Freitag", 6: "Samstag" }</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-map-size"><head>map:size</head><glist><gitem><label>Summary</label><def><p>Returns the number of entries in the supplied map.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="map" name="size" return-type="xs:integer" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="map" type="map(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function <function>map:size</function> takes any <termref def="dt-map">map</termref>
            as its <code nobreak="false">$map</code> argument and returns the number of entries that are present
            in the map.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">count(map:entries($map))</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:size({})</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">map:size({ "true": 1, "false": 0 })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="xml-to-json-mappings"><head>Converting elements to maps</head><changes><change issue="528 1645 1646 1647 1648 1658 1658 1797" PR="1575 1906" date="2024-11-19">
                  A new function <function>fn:element-to-map</function> is provided for converting XDM trees
                  to maps suitable for serialization as JSON. Unlike the <function>fn:xml-to-json</function> function
                  retained from 3.1, this can handle arbitrary XML as input.
               </change></changes><p>The <function>fn:element-to-map</function> function converts a tree rooted at an XML element node to 
               a corresponding tree of maps, in a form suitable for serialization as JSON. In effect it provides
               a mechanism for converting XML to JSON.</p><p>This section describes the mappings used by this function.</p><p>This mapping is designed with three objectives:</p><ulist><item><p>It should be possible to represent any XML element as a map suitable for JSON serialization.</p></item><item><p>The resulting JSON should be intuitive and easy to use.</p></item><item><p>The JSON should be consistent and stable: small variations in the input should not result
               in large variations in the output.</p></item></ulist><p>Achieving all three objectives requires design compromises. It also requires sacrificing some other
            desiderata. In consequence:</p><ulist><item><p>The conversion is not lossless (see <specref ref="id-loss-of-xdm-information"/> for details).</p></item><item><p>The conversion is not streamable.</p></item><item><p>The results are not necessarily compatible with those produced by other popular libraries.</p></item></ulist><p>The requirement for consistency and stability is particularly challenging. An element such as 
            <code nobreak="false">&lt;name&gt;John&lt;/name&gt;</code> maps naturally to the map <code nobreak="false">{ "name": "John" }</code>;
               but adding an attribute (so it becomes <code nobreak="false">&lt;name role="first"&gt;John&lt;/name&gt;</code>)
            then requires an incompatible change in the JSON representation. The format could be made extensible
            by converting <code nobreak="false">&lt;name&gt;John&lt;/name&gt;</code> to <code nobreak="false">{ "name": {"#content":"John"} }</code>
               and <code nobreak="false">&lt;name role="first"&gt;John&lt;/name&gt;</code> to 
               <code nobreak="false">{ "name": { "@role":"first", "#content":"John" } }</code>,
               but this imposes unwanted complexity on the simplest cases. The solution adopted is threefold:</p><ulist><item><p>It is possible to analyze a corpus of XML documents to develop a conversion plan, which can then
               be applied consistently to individual input documents, whether or not these documents were present in the corpus. The
               conversion plan can be serialized and subsequently reused, so that it can be applied to input documents that
               might not have existed at the time the conversion plan was formulated.</p></item><item><p>Alternatively, the function can make 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.</p></item><item><p>It is possible to override the choices made by the system, and explicitly specify the format
               to be used for elements or attributes having a given name.</p></item></ulist><div3 id="id-element-layouts"><head>Element Layouts</head><p>The key challenge in mapping XML to JSON is in deciding how element content is to be represented. To 
                  illustrate the variety of mappings that are possible, the following table
               lists some examples of typical XML elements and their JSON equivalents:</p><table role="data"><thead><tr><th rowspan="1" colspan="1">XML element</th><th rowspan="1" colspan="1">JSON equivalent</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;hr/&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">"hr": ""</eg></td></tr><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;date-of-birth&gt;2023-05-18&lt;/date-of-birth&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">"date-of-birth": "2023-05-18"</eg></td></tr><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;box width="5" height="10"/&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">"box": { "@width": "5", "@height": "10" }</eg></td></tr><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;label id="t41"&gt;Warning!&lt;/label&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">"label": { "@id": "t41", "#content": "Warning!" }</eg></td></tr><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;box&gt;
    &lt;width&gt;5&lt;/width&gt;
    &lt;height&gt;10&lt;/height&gt;
&lt;/box&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">"box": {
    "width": 5, 
    "height": 10
}</eg></td></tr><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;polygon&gt;
    &lt;point x="0" y="0"/&gt;
    &lt;point x="1" y="0"/&gt;
    &lt;point x="1" y="1"/&gt;
    &lt;point x="0" y="1"/&gt;
&lt;/polygon&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">"polygon": [
    { "x": 0, "y": 0 }, 
    { "x": 1, "y": 0 }, 
    { "x": 1, "y": 1 }, 
    { "x": 0, "y": 1 }
]    </eg></td></tr></tbody></table><p>This specification defines a
               number of named mappings, called <term>layouts</term>, and allows the layout for a particular
               element to be selected in a number of different ways:</p><ulist><item><p>The layout to be used for a specific elements can be explicitly selected by
                     supplying a conversion plan as input
                     to the <function>fn:element-to-map</function> function.</p></item><item><p>It is possible to construct a conversion plan by analyzing a corpus of documents
                  using the <function>fn:element-to-map-plan</function> function.</p></item><item><p>It is also possible to construct a conversion plan manually, or to modify
                  the conversion plan produced by the <function>fn:element-to-map-plan</function> function
                     before use.</p></item><item><p>In the absence of an explicit conversion plan, if the data has been schema-validated, the layout is 
                     inferred from the content model for the element type as defined in the schema.</p></item><item><p>When the data is untyped and no specific layout has been selected, 
                     a default layout is chosen based on the properties of the individual element instance.</p></item></ulist><p>The advantage of using schema information is that it gives a consistent representation for all
               elements of a particular type, even if they vary in content: for example if an element type allows optional
               attributes, the JSON representation will be consistent between those elements that have attributes and those
               without. In the absence of a schema, consistency can be achieved by supplying a conversion plan that
               applies uniformly to multiple documents.</p><p>The different layouts available are defined in the following sections. For each layout
               there is a table showing:</p><ulist><item><p><term>Layout name</term>: the name to be used to select this layout in
                  a conversion plan supplied to the <function>fn:element-to-map</function> function.</p></item><item><p><term>Usage</term>: the situations for which this layout is designed.</p></item><item><p><term>Example input</term>: an example of a typical element for which this layout is appropriate,
                     shown as serialized XML.</p></item><item><p><term>Example output</term>: the result of converting this example, shown as serialized JSON. The 
                  result is always shown as a singleton map, which is how it will appear when the layout is used
                  for the top-level elements supplied in the <code nobreak="false">$elements</code> argument; when used to convert
                     a descendant element, the corresponding key-value pair may appear as part of a larger map, depending
                     on the layout chosen for its parent element..</p><note><p>The <function>fn:element-to-map</function> function produces a map as its result, but it is convenient
                  to illustrate the form of the map by showing the effect of serializing the map as JSON.</p></note></item><item><p><term>Mapping rules</term>: The rules for mapping the XML element to an XDM map
                  representation.</p></item><item><p><term>Mapping for nilled elements</term>: special rules that apply to an
                  element having the attribute <code nobreak="false">xsi:nil="true"</code>. These rules only apply if the
                  element has been schema-validated.</p></item><item><p><term>Errors</term>: situations where the layout cannot be used, and where attempting
                     to use it will fail. For example, the <code nobreak="false">empty</code> layout cannot be used for
                     an element that is not empty. In such a situation the recovery action is as follows, in order:</p><olist><item><p>Attributes are dropped, and if this is sufficient to enable the layout
                        to be used, then the element is converted without its attributes.</p></item><item><p>If the <code nobreak="false">type</code> of an element or attribute in the conversion
                        plan is given as <code nobreak="false">boolean</code> or <code nobreak="false">numeric</code>, but the actual
                        value of the element or attribute is not castable to <code nobreak="false">xs:boolean</code>
                        or <code nobreak="false">xs:numeric</code> respectively, then the node is output ignoring
                        the <code nobreak="false">type</code> property, that is, as an instance of <code nobreak="false">xs:untypedAtomic</code>.</p></item><item><p>If the conversion plan supplies a fallback layout (an entry with key
                        <code nobreak="false">"*"</code>), then the fallback layout is used.</p></item><item><p>The <function>element-to-map</function> function fails with
                        a dynamic error.</p></item></olist></item></ulist><p>The rules for selecting the layout for a particular element are given later, 
                  in <specref ref="id-selecting-element-layout"/>.</p><p>Note that it is possible to request any layout for any element. If an inappropriate layout
               is chosen for a particular element (for example, <code nobreak="false">empty</code> layout for an element
                  that is not empty), then the rules for that layout specify what happens.
               It is possible to specify a fallback layout for use when the selected layout fails: this will typically
               be a layout such as <code nobreak="false">xml</code> or <code nobreak="false">mixed</code> that can handle any element.</p><note><p>Acknowledgements for this categorization: see <bibref ref="Goessner"/>. Although
               Goessner's categories have been used, the detailed mappings vary from his proposal.</p></note><div4 id="id-empty-layout"><head>Layout: Empty Content</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">empty</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended for XML elements that have no content and no attributes.</p></td></tr><tr><th rowspan="1" colspan="1">Example input</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;hr/&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "hr": "" }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1"><p>The content is represented by the zero-length <code nobreak="false">xs:string</code>
                              value <code nobreak="false">""</code>.</p></td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>The content is represented by the QName 
                              <code nobreak="false">fn:QName("http://www.w3.org/2005/xpath-functions", "null")</code>, 
                              which the JSON serialization method serializes as
                              <code nobreak="false">null</code>. For example the result of converting the element
                              <code nobreak="false">&lt;hr xsi:nil="true"/&gt;</code> becomes 
                              <code nobreak="false">{ "hr": #fn:null }</code>, which is serialized in JSON
                               as <code nobreak="false">{ "hr": null }</code>.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>Attributes are discarded, along with child comment nodes, 
                              processing instructions, and whitespace-only text nodes.</p>
                              <p>If any other child nodes are present, this layout fails.</p></td></tr></tbody></table></div4><div4 id="id-empty-plus-layout"><head>Layout: Empty Content with Attributes</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">empty-plus</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended for XML elements that have no content but may have attributes.</p></td></tr><tr><th rowspan="1" colspan="1">Example input</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;hr class="ccc" id="zzz"/&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "hr": { "@class": "ccc", "@id": "zzz" } }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1"><p>The content is represented by a map containing one entry for each
                              attribute in the XML element; if there are no attributes, the content
                              is represented as the empty map. 
                              The rules for attribute names are
                           defined in <specref ref="element-and-attribute-names"/>, and the
                              rules for attribute content in <specref ref="element-and-attribute-content"/>.</p></td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>An additional key-value pair <code nobreak="false">"#content": #fn:null</code> is added, which
                              serializes in JSON as <code nobreak="false">"#content": null</code>. For example
                              <code nobreak="false">&lt;hr id="x" xsi:nil="true"/&gt;</code> becomes 
                              <code nobreak="false">{ "hr": { "@id": "x", "#content": #fn:null } }</code>.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>Child comment nodes, processing instructions, and whitespace-only text
                           nodes are discarded.</p>
                              <p>If any other child nodes are present, this layout fails.</p></td></tr></tbody></table></div4><div4 id="id-simple-layout"><head>Layout: Simple Content</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">simple</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended for XML elements that have simple content and no attributes.</p></td></tr><tr><th rowspan="1" colspan="1">Example input</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;date&gt;2023-05-30&lt;/date&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "date": "2023-05-30" }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1"><p>The element is atomized and the resulting atomized value is handled
                              as described in <specref ref="element-and-attribute-content"/>.
                              If atomization fails, the element is treated as if it were untyped.</p>
                              
                              <note><p>If the element is untyped, the atomized value will always 
                                    appear in the result as an instance of <code nobreak="false">xs:untypedAtomic</code>.</p></note>
                          </td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>The content is represented by the value <code nobreak="false">#fn:null</code>, 
                              which is serialized as the JSON value <code nobreak="false">null</code>. For example.
                              <code nobreak="false">&lt;name xsi:nil="true"/&gt;</code> becomes <code nobreak="false">{ "name": #fn:null }</code>.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>Attributes are discarded, along with child comment nodes and processing instructions;
                              whitespace is retained.</p>
                              <p>If any child elements are present, this layout fails.</p>
                              
                           </td></tr></tbody></table></div4><div4 id="id-simple-plus-layout"><head>Layout: Simple Content with Attributes</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">simple-plus</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended for XML elements that have simple content and (optionally) attributes.</p></td></tr><tr><th rowspan="1" colspan="1">Example input</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;price currency="USD"&gt;23.50&lt;/date&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "price": { "@currency": "USD", "#content": 23.50 } }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1"><p>The element is represented by a map containing one entry for each
                              of its attributes, plus an entry with key <code nobreak="false">"#content"</code>
                              representing the result of atomizing the element. The atomized value is handled
                              as described in <specref ref="element-and-attribute-content"/>.</p>
                              <p>The rules for attribute names are
                           defined in <specref ref="element-and-attribute-names"/>, and the
                              rules for attribute content in <specref ref="element-and-attribute-content"/>.</p>
                              <note><p>If the element is untyped, the value of each attribute, and of <code nobreak="false">"#content"</code>,
                                    will always be an instance of <code nobreak="false">xs:untypedAtomic</code>.</p><p>If the element has been schema-validated, the types of the items in the atomized
                                    value are retained.</p></note>
                           </td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>The <code nobreak="false">"#content"</code> property is represented by the value <code nobreak="false">#fn:null</code>, 
                              which is serialized in JSON as <code nobreak="false">null</code>.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>Child comment nodes and processing instructions are discarded;
                              whitespace is retained.</p>
                              <p>If any child elements are present, this layout fails.</p>
                           </td></tr></tbody></table></div4><div4 id="id-list-layout"><head>Layout: Simple List</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">list</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended for XML elements that act as wrappers for a list of child elements,
                              all having the same element name; neither the element itself nor any of its
                              children should have any attributes. The expected child element name may
                              be present in the conversion plan.
                              The names of the child elements are not retained in the output.</p></td></tr><tr><th rowspan="1" colspan="1">Example input (1)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;dates&gt;
  &lt;date&gt;2023-03-20&lt;/date&gt;
  &lt;date&gt;2023-04-12&lt;/date&gt;
  &lt;date&gt;2023-05-30&lt;/date&gt;
&lt;/dates&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output (1)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "dates": [ "2023-03-20", "2023-04-12", "2023-05-30" ] }</eg></td></tr><tr><th rowspan="1" colspan="1">Example input (2)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;dates&gt;
  &lt;date&gt;&lt;year&gt;2023&lt;/year&gt;&lt;month&gt;03&lt;/month&gt;&lt;day&gt;20&lt;/day&gt;&lt;/date&gt;
  &lt;date&gt;&lt;year&gt;2023&lt;/year&gt;&lt;month&gt;04&lt;/month&gt;&lt;day&gt;12&lt;/day&gt;&lt;/date&gt;
  &lt;date&gt;&lt;year&gt;2023&lt;/year&gt;&lt;month&gt;05&lt;/month&gt;&lt;day&gt;30&lt;/day&gt;&lt;/date&gt;
&lt;/dates&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output (2)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "dates": [ 
    { "year": "2023", "month": "03", "day": "20" },
    { "year": "2023", "month": "04", "day": "12" },
    { "year": "2023", "month": "05", "day": "30" }
  ] }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1"><p>The content is represented by an array,
                                 whose members correspond one-to-one with the children of the element.
                                 Each child element is converted to a map as if it were a top-level element:
                                 the resulting map contains a single key-value pair. The key part is discarded,
                                 and the value part is used as a member in the resulting array.</p> 
                             
                              <p>If there are no children then the content is represented by the empty array.</p>
                              
                              </td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>The array is replaced by the value <code nobreak="false">#fn:null</code>, 
                              which serializes to the JSON value 
                              <code nobreak="false">null</code> (for example <code nobreak="false">{ "dates": #fn:null }</code>).</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>Attributes are discarded for both the element itself, and its children.
                              Comments, processing instructions, and whitespace text nodes in the content are discarded.</p>
                              <p>This layout fails if any child element is present with a name that
                                 differs from the expected child element name, or if there are non-whitespace
                                 text node children.</p></td></tr></tbody></table></div4><div4 id="id-list-plus-layout"><head>Layout: List with Attributes</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">list-plus</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended for XML elements that act as wrappers for a list of child elements,
                              all having the same element name. The wrapper element may have attributes,
                              but the children should not.
                              and the name of the child elements is retained in the output.</p></td></tr><tr><th rowspan="1" colspan="1">Example input (1)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;dates id="x"&gt;
  &lt;date&gt;2023-03-20&lt;/date&gt;
  &lt;date&gt;2023-04-12&lt;/date&gt;
  &lt;date&gt;2023-05-30&lt;/date&gt;
&lt;/dates&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output (1)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">"dates": { "@id": "x", "date": ["2023-03-20", "2023-04-12", "2023-05-30"]}</eg></td></tr><tr><th rowspan="1" colspan="1">Example input (2)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;dates id="x"&gt;
  &lt;date&gt;&lt;year&gt;2023&lt;/year&gt;&lt;month&gt;03&lt;/month&gt;&lt;day&gt;20&lt;/day&gt;&lt;/date&gt;
  &lt;date&gt;&lt;year&gt;2023&lt;/year&gt;&lt;month&gt;04&lt;/month&gt;&lt;day&gt;12&lt;/day&gt;&lt;/date&gt;
  &lt;date&gt;&lt;year&gt;2023&lt;/year&gt;&lt;month&gt;05&lt;/month&gt;&lt;day&gt;30&lt;/day&gt;&lt;/date&gt;
&lt;/dates&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output (2)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "dates": {
   "@id": "x", 
   "date": [ 
    { "year": "2023", "month": "03", "day": "20" },
    { "year": "2023", "month": "04", "day": "12" },
    { "year": "2023", "month": "05", "day": "30" }
  ] } }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1">
                              <p>The content is represented by a map containing one entry for each
                                 attribute in the XML element, plus a property named after the 
                                 child elements (the <term>content property</term>), whose value is an array 
                                 containing the results of formatting the content in the same way as the 
                                 <code nobreak="false">list</code> layout.</p> 
                              
                              <p>If there are no children and the element is untyped (which can occur when 
                                 this layout is chosen explicitly via the options to <function>fn:element-to-map</function>)
                                 then the content property is omitted (since the child element name is unknown).
                                 But if the element is typed, then the content property is included and set to
                                 the empty array.</p>
                              
                           </td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>The array-valued entry in the result is replaced by the entry
                              <code nobreak="false">"#content": #fn:null</code>, 
                              which serializes to the JSON value <code nobreak="false">null</code>. 
                              For example the element <code nobreak="false">&lt;dates id="x" xsi:nil="true"/&gt;</code>
                              becomes <code nobreak="false">{"dates": { "@id": "x", "#content": #fn:null } }</code>.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>Any attributes on the element's children are discarded.
                              Comments, processing instructions, and whitespace text nodes in the content are discarded.</p>
                              <p>This layout fails if any child element is present with a name that
                                 differs from the expected child element name, or if there are non-whitespace
                                 text node children.</p>
                           </td></tr></tbody></table></div4><div4 id="id-record-layout"><head>Layout: Record</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">record</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended primarily for XML elements that contain multiple child elements, with different
                              names, where the order of the child elements is not significant. Also used for elements
                              whose content is a single element node child.
                              The element may or may not have attributes.</p></td></tr><tr><th rowspan="1" colspan="1">Example input (1)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;employee id="x"&gt;
  &lt;date-of-birth&gt;1984-03-20&lt;/date&gt;
  &lt;location&gt;Germany&lt;/location&gt;
  &lt;position&gt;Janitor&lt;/position&gt;
&lt;/employee&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output (1)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">
{ "employee": { "@id": "x", 
                "date-of-birth": "1984-03-20", 
                "location": "Germany", 
                "position": "Janitor"
              }
}</eg></td></tr><tr><th rowspan="1" colspan="1">Example input (2)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;employee id="x"&gt;
  &lt;date-of-birth&gt;1984-03-20&lt;/date&gt;
  &lt;location&gt;Germany&lt;/location&gt;
  &lt;position&gt;Janitor&lt;/position&gt;
  &lt;position&gt;Gardener&lt;/position&gt;
&lt;/employee&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output (2)</th><td rowspan="1" colspan="1"><eg xml:space="preserve">
{ "employee": { "@id": "x", 
                "date-of-birth": "1984-03-20", 
                "location": "Germany", 
                "position": [ "Janitor", "Gardener" ]
              }
}</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1">
                              <p>The content is represented by a map containing one entry for each
                                 attribute in the XML element, plus one entry for each
                                 child element, whose value is formatted according to the rules for that element.</p>
                              
                              <p>If two or more child elements have the same name, or names that are represented by
                              the same string (taking into account the chosen <code nobreak="false">name-format</code> option),
                              then they are combined into a single entry containing all the corresponding values
                              as members of an array. For example, if there are two children 
                              <code nobreak="false">&lt;author&gt;Mills&lt;/author&gt;</code> and <code nobreak="false">&lt;author&gt;Boon&lt;/author&gt;</code>,
                              they are combined into a single entry <code nobreak="false">"author": ["Mills", "Boon"]</code>.</p>
                             
                              <p>The <xtermref spec="DM40" ref="dt-entry-order"/> of the resulting map
                                 first contains entries derived from attributes (in unpredictable order),
                                 then entries derived from child elements, in order of first appearance.</p>
                              
                              </td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>Alongside any attributes, the value includes the additional entry
                              <code nobreak="false">"#content": #fn:null</code>, which will be serialized 
                              in JSON as <code nobreak="false">"#content": null</code>.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>Although this layout is intended primarily for elements whose children are unordered
                              and uniquely named, it is also viable to use it in cases where elements can repeat, so
                              long as order relative to other elements is not significant.</p>
                              <p>Comments, processing instructions, and whitespace text nodes in the content are discarded.</p>
                              <p>This layout fails if there are non-whitespace
                                 text node children.</p>
                           </td></tr></tbody></table></div4><div4 id="id-sequence-layout"><head>Layout: Sequence</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">sequence</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended for XML elements that contain a sequence of element node children,
                              whose order is significant. 
                              The element may or may not have attributes.</p></td></tr><tr><th rowspan="1" colspan="1">Example input</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;section id="x"&gt;
   &lt;head&gt;Introduction&lt;/head&gt;
   &lt;p&gt;Lorem ipsum.&lt;/p&gt;
   &lt;p&gt;Dolor sit amet.&lt;/p&gt;
&lt;/section&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "section": [
      { "@id": "x" },                        
      { "head": "Introduction" },
      { "p": "Lorem ipsum." },
      { "p": "Dolor sit amet." }
   ] }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1"><p>The mapping rules are identical to the rules for the <code nobreak="false">mixed</code> layout (see 
                              <specref ref="id-mixed-layout"/>) except that whitespace-only text nodes
                              are discarded.</p>
                           </td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>A nilled element is indicated by including an additional map 
                              <code nobreak="false">{ "#content" : #fn:null}</code> in the array, after
                              any attributes.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>This layout fails if there are non-whitespace
                                 text node children.</p>
                           </td></tr></tbody></table></div4><div4 id="id-mixed-layout"><head>Layout: Mixed</head><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">mixed</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>Intended for XML elements that contain mixed content (that is, elements
                              that contain both child elements and child text nodes, intermingled). 
                              The element may or may not have attributes.</p></td></tr><tr><th rowspan="1" colspan="1">Example input</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;para id="x"&gt;This is a &lt;i&gt;fine&lt;/i&gt; mess!&lt;/para&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "para": [
     { "@id": "x" },
     "This is a ",
     { "i": "fine" },
     "mess!"
   ] }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1"><p>The content is represented by an XDM array containing one entry for each
                                 attribute in the XML element, and one entry for each child node, 
                              in order. </p>
                              <p>Each attribute node is represented within this array by a single-entry
                              map: the rules for attribute names are
                           defined in <specref ref="element-and-attribute-names"/>, and the
                              rules for attribute content in <specref ref="element-and-attribute-content"/>.</p>
                              <p>Child nodes are represented within the array as follows:</p>
                              <ulist><item><p>A text node child is represented as an atomic item of type 
                                    <code nobreak="false">xs:untypedAtomic</code>.</p></item><item><p>An element node child is represented as a map containing a single
                                 entry, with the key representing the element name and the value representing the
                                 element's content, formatted according to the chosen layout for that element.</p></item><item><p>A comment node is represented as a map containing a single
                                 entry whose key is the string <code nobreak="false">"#comment"</code>, and whose corresponding
                                 value is an atomic item of type <code nobreak="false">xs:string</code> containing the text of the comment.</p></item><item><p>A processing instruction node is represented as a map containing 
                                    a single entry whose key is the string <code nobreak="false">"#processing-instruction"</code> 
                                    and whose value is a map with two entries: the first has the key <code nobreak="false">"#target"</code>
                                    with the value being the name of the processing instruction as an atomic item
                                    of type <code nobreak="false">xs:NCName</code>; the second has the key <code nobreak="false">"#data"</code> with
                                    the value being an atomic item of type <code nobreak="false">xs:string</code> containing the 
                                    string value of the processing instruction node.</p></item></ulist>
                              
                              <p>Whitespace text nodes are retained.</p>
                               
                            
                           </td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>A nilled element is indicated by including an additional map 
                              <code nobreak="false">{ "#content" : #fn:null}</code> in the array, after
                              any attributes.
                              For example, <code nobreak="false">&lt;para id="p2" xsi:nil="true"/&gt;</code>
                              becomes <code nobreak="false">{"para": [ { "id": "p2" }, { "#content": #fn:null } ] }</code>.
                           In JSON the value <code nobreak="false">#fn:null</code> 
                              is serialized as <code nobreak="false">null</code>.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>All children are retained, including comments, processing instructions, and
                           text nodes, whether or not they are whitespace-only.</p>
                           <p>This layout never fails.</p></td></tr></tbody></table></div4><div4 id="id-xml-layout"><head>Layout: Serialized XML</head><p>Serialized layout allows an element node to be represented as lexical XML, contained within a map.</p><table role="data"><tbody><tr><th rowspan="1" colspan="1">Layout name</th><td rowspan="1" colspan="1"><p><code nobreak="false">xml</code></p></td></tr><tr><th rowspan="1" colspan="1">Usage</th><td rowspan="1" colspan="1"><p>This layout is useful when the input contains a mix of
                              structured data and marked-up textual content. It allows the
                              textual content to be output as serialized XML. It is also used
                           as a fallback representation when the selected element layout is
                           inappropriate for a particular element.</p></td></tr><tr><th rowspan="1" colspan="1">Example input</th><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;p&gt;That was &lt;i&gt;awesome&lt;/i&gt;&lt;/p&gt;</eg></td></tr><tr><th rowspan="1" colspan="1">Example output</th><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "p": "&lt;p&gt;That was &lt;i&gt;awesome&lt;/i&gt;&lt;/p&gt;" }</eg></td></tr><tr><th rowspan="1" colspan="1">Mapping rules</th><td rowspan="1" colspan="1"><p>The element node is serialized as if by the <function>fn:serialize</function>
                              function, and the resulting content is output as an atomic item of type 
                              <code nobreak="false">xs:string</code>.</p>
                              <p>The serialization parameter <code nobreak="false">method</code> is set to
                              <code nobreak="false">"xml"</code>.</p>
                              <p>The serialization parameter <code nobreak="false">indent</code> is set to <code nobreak="false">false</code>.</p>
                              <p>The serialization parameter <code nobreak="false">omit-xml-declaration</code> is set
                                 to true.</p>
                              <p>Other serialization parameters take their default values.</p>
                              <note><p>The outermost element name will typically be repeated, for example
                              <code nobreak="false">"p": "&lt;p&gt;Lorem ipsum&lt;/p&gt;"</code>.</p></note>
                           </td></tr><tr><th rowspan="1" colspan="1">Mapping for nilled elements</th><td rowspan="1" colspan="1"><p>A nilled element is represented using its normal XML serialization,
                              that is, the output serialization includes the attribute <code nobreak="false">xsi:nil="true"</code>,
                              together with a declaration of the <code nobreak="false">xsi</code> namespace prefix.</p></td></tr><tr><th rowspan="1" colspan="1">Errors</th><td rowspan="1" colspan="1"><p>This layout never fails.</p></td></tr></tbody></table></div4></div3><div3 id="id-creating-a-conversion-plan"><head>Creating a conversion plan</head><p>It is possible to create a conversion plan by analyzing a collection of sample input documents.
               The function <function>fn:element-to-map-plan</function> is supplied with a collection
               of nodes (which will normally be element or document nodes), and it examines all the elements within
               the trees rooted at these nodes, looking for commonalities among like-named elements.</p><p>The output of this function (the conversion plan) holds information about how elements and attributes
                  (identified by name) should be converted.</p><p>For elements, the information is primarily a mapping from element names
               (<code nobreak="false">xs:QName</code> instances) to layout names. In some cases additional information beyond
               the layout name is also included. The conversion plan is represented as an XDM map, whose structure
               is defined in this specification. A conversion plan can be constructed directly, or the plan
               produced by calling <function>fn:element-to-map-plan</function> can be modified
               before use. The plan can be serialized using the JSON output method and reloaded so that the same
               plan is used whenever a query or stylesheet is executed.</p><p>The <function>fn:element-to-map-plan</function> function selects a layout for a given
               element name <var>N</var> by applying the following rules:</p><olist><item><p>Let <code nobreak="false">$EE</code> be
                  the set of all elements named <var>N</var>, specifically
                  <code nobreak="false">$input/descendant-or-self::*[node-name(.) eq <var>N</var>]</code>. </p></item><item><p>If <code nobreak="false">empty($EE/(* | text())</code> (that is, if there 
                        are no child elements or text nodes) then:</p><olist><item><p>If <code nobreak="false">empty($EE/@*)</code> (that is, if there 
                           are no attributes),
                           then the layout is <code nobreak="false">empty</code>: see <specref ref="id-empty-layout"/>.</p></item><item><p>Otherwise, the layout is <code nobreak="false">empty-plus</code>: see <specref ref="id-empty-plus-layout"/>.</p></item></olist></item><item><p>If <code nobreak="false">empty($EE/*)</code> (that is, if there are no child elements) then:</p><olist><item><p>If <code nobreak="false">empty($EE/@*)</code> (that is, if there 
                           are no attributes)
                           then the layout is <code nobreak="false">simple</code>: see <specref ref="id-simple-layout"/>.</p></item><item><p>Otherwise, <code nobreak="false">simple-plus</code>: see <specref ref="id-simple-plus-layout"/>.</p></item><item><p>The plan also includes the property <code nobreak="false">type</code>. If all the elements
                        in <code nobreak="false">$EE</code> are castable as <code nobreak="false">xs:boolean</code>, then the type is <code nobreak="false">boolean</code>;
                        otherwise, if all the elements in <code nobreak="false">$EE</code> as castable as <code nobreak="false">xs:numeric</code>,
                        then the type is <code nobreak="false">numeric</code>; otherwise, the type is <code nobreak="false">string</code>.</p></item></olist></item><item><p>If <code nobreak="false">empty($EE/text()[normalize-space()])</code> (that is, there are no text node
                     children other than whitespace), then:</p><olist><item><p>If <code nobreak="false">all-equal($EE/*/node-name()) and exists($EE/*[2])</code>
                           (that is, if all child elements have the same name, and at least one element has multiple child
                           elements), then:</p><olist><item><p>If <code nobreak="false">empty($EE/@*)</code> (that is, if there 
                                 are no attributes)
                                 then <code nobreak="false">list</code>: see <specref ref="id-list-layout"/>.</p></item><item><p>Otherwise, <code nobreak="false">list-plus</code>: see <specref ref="id-list-plus-layout"/>.</p></item></olist></item><item><p>If <code nobreak="false">every $e in $EE satisfies all-different($e/*/node-name())</code>
                           (that is, the child elements are uniquely named among their siblings),
                           then <code nobreak="false">record</code>: see <specref ref="id-record-layout"/>.</p></item><item><p>Otherwise, <code nobreak="false">sequence</code>: see <specref ref="id-sequence-layout"/>.</p></item></olist></item><item><p>Otherwise, <code nobreak="false">mixed</code>: see <specref ref="id-mixed-layout"/>.</p></item></olist><p>For elements with simple content (more specifically, elements where the chosen layout is
               <code nobreak="false">simple</code> or <code nobreak="false">simple-plus</code>) the conversion plan also includes an entry indicating
               whether the content should be represented as a boolean, a number, or a string. If every instance of
               the element name has content that is castable to <code nobreak="false">xs:boolean</code>, the plan indicates
               <code nobreak="false">"type": "boolean"</code>. If every instance of
               the element name has content that is castable to <code nobreak="false">xs:numeric</code>, the plan indicates
               <code nobreak="false">"type": "numeric"</code>. In other cases, the plan indicates <code nobreak="false">"type": "string"</code>; however,
               this may be omitted because it is the default.</p><p>For attributes, the conversion plan identifies whether attributes (with a given name)
               should be represented as booleans, numbers, or strings; alternatively, it may indicate
               that attributes with a given name should be discarded. For every distinct attribute name present
               in the input, an entry is output associating the attribute name with one of the types
               <code nobreak="false">boolean</code> or <code nobreak="false">numeric</code>; the entry is generally omitted when the values are to 
               be represented as strings, though the type can also be given explicitly as <code nobreak="false">string</code>. 
               An entry with type <code nobreak="false">boolean</code>
               is generated for an attribute name if all the attributes with that name are castable as <code nobreak="false">xs:boolean</code>.
               Similarly, an entry with type <code nobreak="false">numeric</code> is generated for an attribute name if all the 
               attributes with that name are castable as <code nobreak="false">xs:numeric</code>. In other case, the attributes are
               treated as being of type <code nobreak="false">string</code>. Entries with type
               <code nobreak="false">string</code> may be omitted, since that is the default.
               The entry for an attribute may also specify <code nobreak="false">"type": "skip"</code>
               to indicate that the attribute should be discarded.</p><p>A plan that is produced by analyzing a corpus of input documents
                  can then be customized by the user if required. For example:</p><ulist><item><p>If <code nobreak="false">simple</code> layout is chosen for a particular element name, but
                  it is known that some documents might be encountered in which that element
                  has attributes, then <code nobreak="false">simple</code> might be changed to <code nobreak="false">simple-plus</code>.</p></item><item><p>If <code nobreak="false">record</code> layout is chosen for a particular element name, but
                  it is known that some documents might be encountered in which child elements
                  can be repeated, then <code nobreak="false">record</code> might be changed to <code nobreak="false">sequence</code>.</p></item><item><p>If a generated plan determines that phone numbers should be represented as numbers,
                  it might be modified to treat them as strings.</p></item></ulist><p>The conversion plan is a map of type <code nobreak="false">map(xs:string, record(*))</code>.
                  The key is an element or attribute name, representing element names in the form <code nobreak="false">Q{uri}local</code>,
                  and attributes in the form <code nobreak="false">@Q{uri}local</code>notation: in both cases the <code nobreak="false">Q{uri}</code>
                  part <rfc2119>must</rfc2119> be omitted for a name in no namespace. Strings
                  are used as keys in preference to <code nobreak="false">xs:QName</code> instances to allow the plan to be serialized
                  in JSON format.</p><p>A more detailed definition of the structure is given in <specref ref="id-conversion-plan-structure"/>.</p><p>A small example might be (in its JSON serialization):</p><eg xml:space="preserve">
{ "bookList": { "layout": "list", "child": "book" },
  "book": { "layout": "record" },
  "author": { "layout": "simple" },
  "title": { "layout": "simple" },
  "price": { "layout": "simple", "type": "numeric" },
  "hardback": { "layout": "simple", "type": "boolean" },
  "@out-of-print": { "type": "boolean" },
  "@Q{http://www.w3.org/2001/XMLSchema-instance}nil": { "type": "skip" }
}  
               </eg></div3><div3 id="id-xsi-attributes"><head>Attributes in the <code nobreak="false">xsi</code> namespace</head><p>This section defines modifications to the above rules that apply to elements having
               attributes in the <code nobreak="false">xsi</code> namespace (that is, 
                  <code nobreak="false">http://www.w3.org/2001/XMLSchema-instance</code>).</p><ulist><item><p>When analyzing a corpus using <function>fn:element-to-map-plan</function>,
                  elements having the attribute <code nobreak="false">xsi:nil="true"</code> are ignored. If all
                  elements with a given name have this attribute, allocate the layout <code nobreak="false">mixed</code>.</p></item><item><p>When deciding whether an element has any attributes (for example to decide
                        between the layouts <code nobreak="false">empty</code> and <code nobreak="false">empty-plus</code>),
                        all attributes in the <code nobreak="false">xsi</code> namespace are ignored.</p></item><item><p>When converting an individual element to a map, 
                        all attributes in the <code nobreak="false">xsi</code> namespace are ignored.</p></item><item><p>Notwithstanding the above, elements having the <code nobreak="false">nilled</code> property
                  (which essentially means they are schema-validated and have the attribute <code nobreak="false">xsi:nil="true"</code>),
                  are treated specially by each of the possible element layouts.</p></item></ulist></div3><div3 id="id-conversion-plan-structure"><head>Structure of the conversion plan</head><p>This section provides a definition of the structure of the
               conversion plan that is output by the <function>fn:element-to-map-plan</function>
               function, and used as input to the <function>fn:element-to-map</function>
               function.</p><p>The structure is defined by the following item type:</p><eg xml:space="preserve">
map( xs:string,
     ( fn:element-conversion-plan-record |
       fn:attribute-conversion-plan-record )
   )                            
               </eg><p>This makes use of two built-in record definitions defined below.</p><p>The rules relating to this structure are as follows:</p><olist><item><p>The keys of the map entries are strings of the form:</p><olist><item><p><code nobreak="false">local-name</code> representing the name of an element in no namespace.</p></item><item><p><code nobreak="false">Q{uri}local-name</code> representing the name of an element in a namespace.</p></item><item><p><code nobreak="false">*</code> representing a fallback rule for use with elements where either
                        (a) there is no more specific rule, or (b) processing using the selected layout
                        fails.</p></item><item><p><code nobreak="false">@local-name</code> representing the name of an attribute in no namespace.</p></item><item><p><code nobreak="false">@Q{uri}local-name</code> representing the name of an attribute in a namespace.</p></item></olist><p>Any entries whose keys are not in this format will be ignored.</p></item><item><p>If the key starts with <code nobreak="false">@</code>, the corresponding value must be
                     of type <code nobreak="false">fn:attribute-conversion-plan-record</code>; otherwise, it
                     must be of type <code nobreak="false">fn:element-conversion-plan-record</code>.</p></item><item><p>In an <specref ref="element-conversion-plan-record"/>:</p><olist><item><p>The <code nobreak="false">layout</code> entry is always present.</p></item><item><p>The <code nobreak="false">child</code> entry is present if and only if the value of <code nobreak="false">layout</code> is
                           <code nobreak="false">list</code> or <code nobreak="false">list-plus</code>. It represents an element name in the format
                           <code nobreak="false">local-name</code> for a name in no namespace, or <code nobreak="false">Q{uri}local-name</code> for a
                           name in a namespace.</p></item><item><p>The <code nobreak="false">type</code> entry is present if and only if the 
                              <code nobreak="false">layout</code> is <code nobreak="false">simple</code> or <code nobreak="false">simple-plus</code>.</p></item></olist></item><item><p>In an <specref ref="attribute-conversion-plan-record"/>:</p><olist><item><p>The <code nobreak="false">type</code> entry is always present.</p></item></olist></item></olist><p>If additional entries (beyond those described above) are present in any of the maps, they
               are ignored, provided that the map is coercible to the given type definition.</p><p>The fallback rule (with key <code nobreak="false">"*"</code>) is used to process elements whose name has no
               specific entry, and also for elements where normal processing fails (for example when the
               selected layout is <code nobreak="false">"empty"</code>, but the element has children). If no fallback rule
               is present then <code nobreak="false">"error"</code> is assumed: this causes processing to fail with a dynamic
               error. The fallback rule will typically set the <code nobreak="false">layout</code> property to one of the following:</p><ulist><item><p><code nobreak="false">error</code>: this causes the function to fail with a dynamic error.</p></item><item><p><code nobreak="false">deep-skip</code>: this causes the element and its content (recursively)
                  to be omitted from the output.</p></item><item><p><code nobreak="false">mixed</code>: this causes the element to be output using layout <code nobreak="false">mixed</code></p></item><item><p><code nobreak="false">xml</code>: this outputs the element to be output using layout <code nobreak="false">xml</code>,
                     which represents the content as a string containing serialized XML.</p></item></ulist><p>However, any layout may be used as the fallback; if it fails, the error is unrecoverable.</p><div4 id="element-conversion-plan-record"><head>Record fn:element-conversion-plan-record</head><p>This record type represents a plan for converting elements
            to maps during evaluation of <function>fn:element-to-map</function>.</p><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Name</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">layout</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>Defines the overall strategy for converting the element content.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">enum('empty', 'empty-plus',                             'simple', 'simple-plus',                             'list', 'list-plus',                             'record', 'sequence', 'mixed', 'xml',                             'error', 'deep-skip')</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">child?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>For list layouts, defines the name of the child element type contained in the list.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">type?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>For elements with simple content, defines whether they should be represented
               as numbers or booleans instead of the default representation as strings.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">enum('numeric', 'boolean', 'string')</code></p></item></ulist></td></tr></tbody></table></div4><div4 id="attribute-conversion-plan-record"><head>Record fn:attribute-conversion-plan-record</head><p>This record type represents a plan for converting attributes
            to atomic items during evaluation of <function>fn:element-to-map</function>.</p><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Name</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">type</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>Defines whether attributes should be represented
               as numbers or booleans instead of the default representation as strings;
               alternatively, indicates that the attribute should be omitted.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">enum('numeric', 'boolean', 'string', 'skip')</code></p></item></ulist></td></tr></tbody></table></div4></div3><div3 id="id-schema-based-conversion"><head>Schema-based conversion</head><p>As an alternative to constructing a conversion plan by analyzing a corpus of specimen documents,
               conversion may be controlled using type annotations derived from schema validation.</p><p>If the function <function>element-to-map</function> encounters an element whose name is
               not present in the conversion plan (including the case where no plan is supplied), and if the
               element has a type annotation <var>T</var> other than <code nobreak="false">xs:anyType</code> or <code nobreak="false">xs:untyped</code>, then
               the following rules apply:</p><note><p>This section uses the notation <code nobreak="false">{prop}</code> to refer to properties
                     of schema components, as defined in <bibref ref="xmlschema11-1"/>. The schema component model
                     from XSD 1.1 is used; when XSD 1.0 is used for validation, some properties
                     such as <code nobreak="false">{open content}</code> will inevitably be absent.</p></note><olist><item><p>Let <code nobreak="false">zeroLength(ST)</code> be true for a simple type <code nobreak="false">ST</code>
                     if any of the following conditions is true:</p><olist><item><p><code nobreak="false">ST.{variety} = list</code>, and <code nobreak="false">ST.{facets}</code> includes
                           a <code nobreak="false">length</code> or <code nobreak="false">maxLength</code> facet whose value is 0 (zero).</p></item><item><p><code nobreak="false">ST.{variety} = atomic</code>, and <code nobreak="false">ST.{facets}</code> includes
                           a <code nobreak="false">length</code> or <code nobreak="false">maxLength</code> facet whose value is 0 (zero).</p></item><item><p><code nobreak="false">ST.{variety} = atomic</code>, and <code nobreak="false">ST.{facets}</code> includes
                           an <code nobreak="false">enumeration</code> facet constraining the value to be zero-length.</p></item><item><p><code nobreak="false">ST.{variety} = atomic</code>, and <code nobreak="false">ST.{facets}</code> includes
                           a <code nobreak="false">pattern</code> facet with the value <code nobreak="false">""</code> (a zero-length string).</p></item></olist></item><item><p>If <var>T</var> is a simple type:</p><olist><item><p>If <code nobreak="false">zeroLength(T)</code>, then the selected layout is <code nobreak="false">empty</code> 
                              (see <specref ref="id-empty-layout"/>).</p></item><item><p>Otherwise, 
                              the selected layout is <code nobreak="false">simple</code> (see <specref ref="id-simple-layout"/>),
                              and the selected type is <code nobreak="false">boolean</code> if <var>T</var> is derived from
                              <code nobreak="false">xs:boolean</code>; <code nobreak="false">numeric</code> if <var>T</var> is derived from
                              <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:double</code>, or <code nobreak="false">xs:float</code>;
                              or <code nobreak="false">string</code> otherwise.</p></item></olist></item><item><p>Otherwise (if <var>T</var> is a complex type):</p><olist><item><p>Let <code nobreak="false">$noAttributes</code> be true if 
                           <code nobreak="false">T.{attribute uses}</code> is empty and <code nobreak="false">T.{attribute wildcard}</code>
                           is absent.</p></item><item><p>If <code nobreak="false">T.{content type}.{variety} = empty</code>, then:</p><olist><item><p>If <code nobreak="false">$noAttributes</code> and if <code nobreak="false">empty</code> layout is not disabled,
                                 then the selected layout is <code nobreak="false">empty</code> (see <specref ref="id-empty-layout"/>).</p></item><item><p>Otherwise, the selected layout is <code nobreak="false">empty-plus</code> (see <specref ref="id-empty-plus-layout"/>).</p></item></olist></item><item><p>If <code nobreak="false">T.{content type}.{variety} = simple</code> 
                              (a complex type with simple content), then:</p><olist><item><p>Let <code nobreak="false">ST</code> be <code nobreak="false">T.{content type}.{simple type definition}</code>
                              (the corresponding simple type).</p></item><item><p>If <code nobreak="false">zeroLength(ST)</code>, then:</p><olist><item><p>If <code nobreak="false">$noAttributes</code>, the selected layout is <code nobreak="false">empty</code> 
                                       (see <specref ref="id-empty-layout"/>).</p></item><item><p>Otherwise, the selected layout is <code nobreak="false">empty-plus</code> 
                                       (see <specref ref="id-empty-plus-layout"/>).</p></item></olist></item><item><p>Otherwise:</p><olist><item><p>If <code nobreak="false">$noAttributes</code>, the selected layout is 
                                       <code nobreak="false">simple</code> (see <specref ref="id-simple-layout"/>).</p></item><item><p>Otherwise the selected layout is <code nobreak="false">simple-plus</code> 
                                       (see <specref ref="id-simple-plus-layout"/>).</p></item><item><p>In both cases the selected type is one of <code nobreak="false">boolean</code>
                                    <code nobreak="false">numeric</code>, or <code nobreak="false">string</code>, chosen in the same way
                                    as for elements having a simple type.</p></item></olist></item></olist></item><item><p>If <code nobreak="false">T.{content type}.{variety} = element-only</code> (a complex type with
                           an element-only content model):</p><olist><item><p>Let <code nobreak="false">$noWildcards</code> be true if <code nobreak="false">T.{content type}.{open content}</code>
                              is absent, and <code nobreak="false">T.{content type}.{particle}</code>, expanded recursively, contains
                              no wildcard term.</p></item><item><p>Let <code nobreak="false">$childCardinalities</code> be a set of (<code nobreak="false">xs:QName</code>, 
                                 <code nobreak="false">xs:double</code>) pairs
                              representing the expanded names of the element declaration terms within 
                                 <code nobreak="false">T.{content type}.{particle}</code>,
                              expanded recursively, and for each one, the maximum number of occurrences of elements
                              with that name, computed
                              using the value of the <code nobreak="false">{maxOccurs}</code> property of the particles at each level, taking the value
                              <code nobreak="false">unbounded</code> as positive infinity.</p></item><item><p>If <code nobreak="false">$noWildcards</code> is true, and if <code nobreak="false">$childCardinalities</code>
                                    contains a single entry, and that entry has a cardinality greater than one, then:</p><olist><item><p>If <code nobreak="false">$noAttributes</code> then 
                                       the selected layout is <code nobreak="false">list</code> (see <specref ref="id-list-layout"/>).</p></item><item><p>Otherwise, the selected layout is <code nobreak="false">list-plus</code> 
                                       (see <specref ref="id-list-plus-layout"/>).</p></item></olist></item><item><p>If <code nobreak="false">$noWildcards</code> is true, and if every entry in <code nobreak="false">$childCardinalities</code>
                                    has a cardinality of one, then the selected layout is
                                    <code nobreak="false">record</code> (see <specref ref="id-record-layout"/>).</p></item><item><p>Otherwise, the selected layout is <code nobreak="false">sequence</code> (see <specref ref="id-sequence-layout"/>).</p></item></olist></item><item><p>Otherwise (that is, when <code nobreak="false">T.{content type}.{variety} = mixed</code>, the
                              selected layout is <code nobreak="false">mixed</code> (see <specref ref="id-mixed-layout"/>).</p></item></olist></item></olist><p>For attribute nodes, the selected type is <code nobreak="false">boolean</code> if the type annotation is derived from
                  <code nobreak="false">xs:boolean</code>; <code nobreak="false">numeric</code> if the type annotation is derived from
                  <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:double</code>, or <code nobreak="false">xs:float</code>;
                  and <code nobreak="false">string</code> otherwise.</p></div3><div3 id="id-selecting-element-layout"><head>Selecting an element layout</head><p>The various layouts available for elements are described in <specref ref="id-element-layouts"/>.
               This section defines the rules for selecting an element layout for a given element <var>E</var>.
               The rules are applied in order.</p><olist><item><p>If an explicit layout is given for the element name of <var>E</var> in the
                  conversion plan supplied to the <function>fn:element-to-map</function> function call, 
                  then that layout is used. If the selected layout is <code nobreak="false">deep-skip</code>,
                     then no output is produced for that element. If the selected layout is <code nobreak="false">error</code>,
                     then the function fails with a dynamic error.
                     If the selected layout fails for the element instance, then
                     the fallback layout (identified with the key <code nobreak="false">"*"</code> in the conversion plan)
                     is used; in the absence of a fallback layout, the function fails with a dynamic error.</p></item><item><p>Otherwise (when no explicit layout is given for <var>E</var>), if the
                  type annotation of the element is something other than <code nobreak="false">xs:untyped</code>
                  or <code nobreak="false">xs:anyType</code>, then a schema-determined layout is used as defined
                  in <specref ref="id-schema-based-conversion"/>.</p></item><item><p>Otherwise, if the conversion plan supplies a fallback layout 
                  (identified with the key <code nobreak="false">"*"</code>), then the fallback layout is used.</p></item><item><p>If the above rules do not provide a layout for <var>E</var>, then
                  a conversion plan for <var>E</var> is determined by applying the rules in 
                  <specref ref="id-creating-a-conversion-plan"/>, with an input that contains
                  the single element <var>E</var> and no others. (Only the element <var>E</var> itself
                  is considered, not its descendants.)</p></item></olist></div3><div3 id="element-and-attribute-names"><head>Element and Attribute Names</head><p>The <code nobreak="false">name-format</code> option gives control over how element and attribute names are formatted.
                  There are four options:</p><ulist><item><p>The default option (which may be explicitly requested by specifying <code nobreak="false">"name-format": "default"</code>)
                  retains the namespace URI for any element that is either (a) the top-level element of a tree being
                  converted, or (b) has a name that is in a different namespace from its parent element. In such cases
                  the format <code nobreak="false">"Q{uri}local"</code> is used. For other elements, the name is output using the
                  local part of the element name alone. For attributes, the form <code nobreak="false">"Q{uri}local"</code> is used
                  for an attribute in a namespace, and the local name alone is used for a no-namespace name.
                  Namespace prefixes are not retained.</p></item><item><p>The option <code nobreak="false">eqname</code> uses the format <code nobreak="false">"Q{uri}local"</code> for all
                  element and attribute names that are in a namespace, or the local name alone for all names 
                  that are not in a namespace.</p></item><item><p>The option <code nobreak="false">local</code> discards all namespace information: all elements and attributes
                  are output using the local name alone.</p></item><item><p>The option <code nobreak="false">lexical</code> outputs element and attribute names in the form 
                     obtained by calling the function <function>fn:name</function>. If the name has a prefix,
                  the prefix is retained in the output. However, the output contains no information that enables the
                  prefix to be associated with a namespace URI, so this format is suitable only when prefixes 
                  in the input documents are used predictably.</p></item></ulist><p>Regardless of the chosen <code nobreak="false">name-format</code>, and regardless of the above rules, 
                  attributes in the <code nobreak="false">xml</code> namespace (<code nobreak="false">http://www.w3.org/XML/1998/namespace</code>)
                  are output using a lexical QName, with the prefix <code nobreak="false">xml</code>.</p><p>Attribute names in the output are typically prefixed with the character <code nobreak="false">"@"</code>.
                  The option <code nobreak="false">attribute-marker</code> allows this to be changed to a different
                  prefix or none.</p><p>Whichever format of names is chosen, if the rules for the selected layout would result in an output
               map having two entries with the same key, the conflict is resolved by combining these
               entries into an array. For example if <code nobreak="false">name-format</code> is set to <code nobreak="false">local</code>
               then the element <code nobreak="false">&lt;data x:val="3" y:val="4"/&gt;</code> becomes either
               <code nobreak="false">{ "data": { "@val": ["3", "4"] } }</code> or (because attribute order is unpredictable)
               <code nobreak="false">{ "data": { "@val": ["4", "3"] } }</code>.</p></div3><div3 id="element-and-attribute-content"><head>Element and Attribute Content</head><p>The conversion plan may indicate that element content is to be output
               as type <code nobreak="false">string</code>, <code nobreak="false">numeric</code>, or <code nobreak="false">boolean</code>: the default
               is <code nobreak="false">string</code>. In the case of untyped elements and attributes, the value is
               output as an instance of a string, numeric, or boolean type, according to this
               prescription. Specifically:</p><ulist><item><p>If the prescribed type is <code nobreak="false">boolean</code> and the value is castable
                  as <code nobreak="false">xs:boolean</code>, then it is output as an instance of <code nobreak="false">xs:boolean</code>.</p></item><item><p>If the prescribed type is <code nobreak="false">numeric</code> and the value is castable
                  as <code nobreak="false">xs:numeric</code>, then it is output as an instance of <code nobreak="false">xs:integer</code>,
                  <code nobreak="false">xs:decimal</code>, or <code nobreak="false">xs:double</code> depending on the lexical form of the
                  value, following the same rules as for XPath numeric literals. For example, <code nobreak="false">"-1"</code>
                  becomes an <code nobreak="false">xs:integer</code>, <code nobreak="false">12.00</code> becomes an <code nobreak="false">xs:decimal</code>,
                  and <code nobreak="false">1e-3</code> becomes an <code nobreak="false">xs:double</code>. The special <code nobreak="false">xs:double</code>
                  values <code nobreak="false">NaN</code> and <code nobreak="false">INF</code> (which cannot be used as numeric literals)
                  are also recognized.</p></item><item><p>In all other cases the value is output as an instance of <code nobreak="false">xs:untypedAtomic</code>,
                     retaining its original lexical form.</p></item></ulist><p>Where the element or attribute is schema-validated, however:</p><olist><item><p>If an element has the <code nobreak="false">nilled</code> property (that is, <code nobreak="false">xsi:nil="true"</code>),
                  then the mapping for nilled elements with the chosen layout is used.</p></item><item><p>Let <var>AV</var> be the typed value of the node (that is, the result
                  of atomization).</p></item><item><p>If, however, an element is annotated with a type that does not allow atomization
                  (specifically, a complex type with element-only content) then let <var>AV</var> be the string value
                  of the element, as an atomic item of type <code nobreak="false">xs:untypedAtomic</code>.</p></item><item><p>If an attribute is annotated as having a simple type of {variety} <code nobreak="false">list</code>,
                     or if an element using layout <code nobreak="false">simple</code> or <code nobreak="false">simple-plus</code>
                     is annotated as having either a simple type of {variety} <code nobreak="false">list</code>
                     or a complex type with simple content of {variety} <code nobreak="false">list</code>
                  then the atomized value <var>AV</var> is represented in the result as the array
                     represented by the XPath expression <code nobreak="false">array{<var>AV</var>}</code>. This applies whether or not the
                  atomized value actually contains multiple atomic items. The individual atomic items in the array retain their type,
                  for example items of type <code nobreak="false">xs:date</code> remain items of type <code nobreak="false">xs:date</code>
                  in the result.</p></item><item><p>In all other cases <var>AV</var> will be a single atomic item, and this value
                     is used <emph>as is</emph>, retaining its type.</p></item></olist><note><p>Atomic items in the result of the <function>fn:element-to-map</function> function
                  may thus be of any atomic type. The type information is lost if the result is 
                  subsequently serialized as JSON.</p></note></div3><div3 id="id-loss-of-xdm-information"><head>Lost XDM Information</head><p>This section is non-normative. Its purpose is to explain what information available
               in the XDM nodes supplied as input to the <function>fn:element-to-map</function> function
               is missing from the output.</p><ulist><item><p><emph>Element and attribute names: </emph> If the chosen 
                  <code nobreak="false">name-format</code> is <code nobreak="false">default</code> or <code nobreak="false">eqname</code>,
                  then local names and namespace URIs of elements and attributes are retained,
                  but namespace prefixes are lost. If the chosen <code nobreak="false">name-format</code> is
                  <code nobreak="false">lexical</code>, then prefixes are retained but namespace URIs are lost.
                  If the chosen <code nobreak="false">name-format</code> is <code nobreak="false">local</code> then only
                  local names are retained; namespace URIs and prefixes are lost.</p><p>In addition, element names are lost when the parent element is mapped
                  using <code nobreak="false">list</code> layout: see <specref ref="id-list-layout"/>.</p></item><item><p><emph>In-scope namespaces: </emph> All information about in-scope namespaces
                  (and in particular, bindings for namespaces that are declared but not used in element
                  and attribute names) is lost.</p></item><item><p><emph>Comments and processing instructions: </emph> Comments and processing instructions
                     are lost except when they appear as children of elements that are mapped using the
                     <code nobreak="false">sequence</code>, <code nobreak="false">mixed</code> or <code nobreak="false">xml</code> layouts.</p></item><item><p><emph>Text nodes: </emph>Whitespace text nodes are discarded when they
                     appear as children of elements that are mapped using the <code nobreak="false">empty</code>,
                     <code nobreak="false">empty-plus</code>, <code nobreak="false">list</code>, <code nobreak="false">list-plus</code>, <code nobreak="false">record</code>,
                     or <code nobreak="false">sequence</code> layouts. Non-whitespace text nodes are never discarded. 
                     </p></item><item><p><emph>Additional node properties: </emph> The values of the <code nobreak="false">is-id</code>,
                     <code nobreak="false">is-idref</code>, and <code nobreak="false">is-nilled</code> properties of a node are lost.</p></item><item><p><emph>Type annotations: </emph> The values of type annotations on elements are lost.
                  Type annotations on atomized values of schema-validated nodes, however, are retained.</p></item><item><p><emph>Element order: </emph> The order of child elements is lost when
                  <code nobreak="false">record</code> layout is used and the element has multiple children with the same name.</p></item><item><p><emph>XSI attributes: </emph> Attributes in the <code nobreak="false">xsi</code> namespace (for example,
                        <code nobreak="false">xsi:type</code> and <code nobreak="false">xsi:nil</code>) are not represented in the result. .</p></item></ulist></div3><div3 id="id-element-to-map-examples"><head>Examples</head><p>The following examples show the effect of transforming some simple XML documents with default options,
               and then serializing the result as JSON with <code nobreak="false">indent</code> is set to <code nobreak="false">true</code>. 
                  The actual indentation is implementation dependent.</p><table class="data"><thead><tr><th rowspan="1" colspan="1">XDM element</th><th rowspan="1" colspan="1">JSON serialization of result</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;a x='1' b='2'/&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "a":{
    "@x": "1",
    "@b": "2"
  } }</eg></td></tr><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;a&gt;&lt;x&gt;1&lt;/x&gt;&lt;y&gt;2&lt;/y&gt;&lt;/a&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "a":{
    "x": "1",
    "y": "2"
  } }</eg></td></tr><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;polygon&gt; 
   &lt;point x='0' y='0'/&gt; 
   &lt;point x='0' y='1'/&gt; 
   &lt;point x='1' y='1'/&gt; 
   &lt;point x='1' y='0'/&gt;
&lt;/polygon&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "polygon":[
       {"@x": "0", "@y": "0"},
       {"@x": "0", "@y": "1"},
       {"@x": "1", "@y": "1"},
       {"@x": "1", "@y": "0"}
  ] ] }</eg></td></tr><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;cities&gt;
   &lt;city id="LDN"&gt;
      &lt;name&gt;London&lt;/name&gt;
      &lt;size&gt;18.2&lt;/size&gt;
   &lt;/city&gt;
   &lt;city id="PRS"&gt;
      &lt;name&gt;Paris&lt;/name&gt;
      &lt;size&gt;19.1&lt;/size&gt;
   &lt;/city&gt;
   &lt;city id="BLN"&gt;
      &lt;name&gt;Berlin&lt;/name&gt;
      &lt;size&gt;14.6&lt;/size&gt;
   &lt;/city&gt;
&lt;/cities&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">{ "cities":[
    {
      "@id": "LDN",
      "name": "London",
      "size": "18.2"
    },
    {
      "@id": "PRS",
      "name": "Paris",
      "size": "19.1"
    },
    {
      "@id": "BLN",
      "name": "Berlin",
      "size": "14.6"
    }
  ] }</eg></td></tr></tbody></table><p>The following more complex example demonstrates a case where the default conversion is
               inadequate (for example, it wrongly assumes that for the third production, the order of child
               elements is immaterial). A better result, shown below, can be achieved by
               using a schema-aware conversion.</p><table class="data"><thead><tr><th rowspan="1" colspan="1">XDM element</th><th rowspan="1" colspan="1">JSON serialization of result</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><eg xml:space="preserve">&lt;g:grammar language="xquery"
    xmlns:g="http://www.w3.org/XPath/grammar"&gt;
  &lt;g:production
    name="FunctionBody"&gt;
    &lt;g:ref name="EnclosedExpr"/&gt;
    &lt;g:ref name="Block"/&gt;
  &lt;/g:production&gt;
  &lt;g:production
    name="EnclosedExpr"&gt;
    &lt;g:ref name="Lbrace"/&gt;
    &lt;g:ref name="Expr"/&gt;
    &lt;g:optional&gt;
      &lt;g:ref name="Expr"/&gt;
    &lt;/g:optional&gt;
    &lt;g:ref name="Rbrace"/&gt;
  &lt;/g:production&gt;
  &lt;g:production
    name="SimpleReturnClause"&gt;
    &lt;g:string&gt;return&lt;/g:string&gt;
    &lt;g:ref name="ExprSingle"/&gt;
  &lt;/g:production&gt;
&lt;/g:grammar&gt;</eg></td><td rowspan="1" colspan="1"><eg xml:space="preserve">[{ "Q{http://www.w3.org/XPath/grammar}grammar": [
  { "@language": "xquery" },
  { "production": [
    { "@name": "FunctionBody" },
    { "ref": { "@name": "EnclosedExpr" } },
    { "ref": { "@name": "Block" } }
  ] },
  { "production": [
    { "@name": "EnclosedExpr" },
    { "ref": { "@name": "Lbrace" } },
    { "ref": { "@name": "Expr" } },
    { "optional":[
      { "ref": { "@name": "Expr" } }
    ] },
    { "ref": { "@name": "Rbrace" } }
  ] },
  { "production": [
    { "@name": "SimpleReturnClause" },
    { "string": "return" },
    { "ref": { "@name": "ExprSingle" } }
  ] }
] }]</eg></td></tr></tbody></table><note><p>In the above example, the schema used to validate the source document was simplified to eliminate
               options that do not actually arise in this input instance (such as the <code nobreak="false">g:string</code>
               element having attributes). This is a legitimate technique that may be useful when trying to obtain 
               the simplest possible JSON representation.</p><p>Further improvements to the usability of the JSON output could be achieved by doing some
               simple transformation of the XML prior to conversion. For example, the <code nobreak="false">name</code>
               attribute of various productions could be converted to a child element, and 
                  <code nobreak="false">&lt;ref name="x"/&gt;</code> could be transformed to <code nobreak="false">&lt;ref&gt;x&lt;/ref&gt;</code>.</p></note></div3><div3 id="func-element-to-map-plan"><head>fn:element-to-map-plan</head><changes><change issue="1797" PR="1906" date="2025-04-29">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Analyzes sample data to generate a conversion plan suitable for use by the <function>element-to-map</function>
            function.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="element-to-map-plan" return-type="map( xs:string,      ( fn:element-conversion-plan-record | fn:attribute-conversion-plan-record )    )  " returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="(document-node() | element())*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function takes as input a collection of document and element nodes and analyzes the trees rooted at these
         nodes to determine a conversion plan for converting elements in these trees to maps, suitable for serialization
         in JSON format. The conversion plan can be used <emph>as-is</emph> by supplying it directly to the 
            <function>element-to-map</function> function; alternatively it can be amended before use. The plan can also
         be serialized to a file (in JSON format) allowing the same plan to be used repeatedly for transforming documents
         with a similar structure to those in the sample provided.</p><p>The rules followed by the function, and the detailed format of the conversion plan, are described
         in <specref ref="id-creating-a-conversion-plan"/>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XQuery expression.</p><eg xml:space="preserve">let $data-type := fn($nodes as node()*) {
  if (every($nodes ! (. castable as xs:boolean))) then "boolean"
  else if (every($nodes ! (. castable as xs:numeric))) then "numeric"
  else ()
}
let $name := fn($node as node()) {
  if (namespace-uri($node)) 
  then expanded-QName(node-name($node))
  else local-name($node)
}  
return (
  for $ee in $input/descendant-or-self::*
  group by $n := $name($ee)
  return { $n :
           if (empty($ee/(*|text())))
             then { 'layout' : if (empty($ee/@*)) 
                               then 'empty' 
                               else 'empty-plus' } 
           else if (empty($ee/*)) 
             then map:merge((
                    if (empty($ee/@*)) 
                      then {'layout': 'simple'}
                      else {'layout': 'simple-plus'},
                    $data-type($ee) ! { 'type': . }
                 ))
           else if (empty($ee/text()[normalize-space()])) 
             then if (all-equal($ee/*/node-name()) and exists($ee/*[2]))
                    then { 'layout': if (empty($ee/@*)) 
                                     then 'list' 
                                     else 'list-plus',
                           'child': $name(head($ee/*))
                         }
                    else { 'layout' : if (every($ee ! all-different(*/node-name())))
                                      then 'record'
                                      else 'sequence'
                         }             
           else {'layout': 'mixed'}
        },
  for $a in $input//@*
  group by $n := $name($a)
  let $t := $data-type($a)
  return $t ! { `@{$n}`: { 'type': $t } }
) =&gt; map:merge()</eg></def></gitem><gitem><label>Notes</label><def><note><p>The conversion plan is organized by element and attribute name, so its effectiveness depends on the 
         <code nobreak="false">$input</code> collection being homogenous in its structure, and representative of the documents
         that will subsequently be converted using the <function>element-to-map</function> function.</p><p>This function is separate from the <function>element-to-map</function> function for a number
         of reasons:</p><ulist><item><p>The collection of documents that need to be analyzed to establish an effective
            conversion plan might be much smaller than the set of documents actually being converted.</p></item><item><p>Conversely, it might be that only a small number of documents need to be converted at 
            a particular time, but the conversion plan used needs to take into account variations that might
            exist within a larger corpus.</p></item><item><p>If JSON output is required in a particular format, it might be necessary to fine-tune
            the automatically generated conversion plan to take account of these requirements.</p></item><item><p>It might be necessary to devise a conversion plan that can be used to convert individual
            documents as they arrive over a period of time, and to ensure that the same conversion rules
            are applied to each document even though documents might exhibit variations in structure.</p></item><item><p>The conversion plan is human-readable, which can help in understanding why the
            output of <function>element-to-map</function> is in a particular form.</p></item></ulist></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
element-to-map-plan(&lt;a&gt;&lt;b&gt;3&lt;/b&gt;&lt;b&gt;4&lt;/b&gt;&lt;/a&gt;)
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
{ 'a': { 'layout': 'list', 'child': 'b' },
  'b': { 'layout': 'simple', 'type': 'numeric' }
}
               </eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
element-to-map-plan((&lt;a x="2"&gt;red&lt;/a&gt;, &lt;a x="3"&gt;blue&lt;/a&gt;))
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
{ 'a': { 'layout': 'simple-plus' },
  '@x': { 'type': 'numeric' }
}
               </eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
element-to-map-plan(
   &lt;a xmlns="http://example.ns"&gt;H&lt;sub&gt;2&lt;/sub&gt;SO&lt;sub&gt;4&lt;/sub&gt;&lt;/a&gt;
)
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
{ 'Q{http://example.ns}a': { 'layout': 'mixed' },
  'Q{http://example.ns}sub': { 'layout': 'simple', 'type': 'numeric' }
}
               </eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
element-to-map-plan((&lt;a&gt;&lt;b/&gt;&lt;b/&gt;&lt;/a&gt;, &lt;a&gt;&lt;b/&gt;&lt;c/&gt;&lt;/a&gt;))
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
{ 'a': { 'layout': 'sequence' },
  'b': { 'layout': 'empty' },
  'c': { 'layout': 'empty' }
}
               </eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-element-to-map"><head>fn:element-to-map</head><changes><change issue="1797" PR="1906" date="2025-04-29">New in 4.0.</change></changes><glist><gitem><label>Summary</label><def><p>Converts an element node into a map that is suitable for
            JSON serialization.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="element-to-map" return-type="map(xs:string, item()?)?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="element" type="element()?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>This function returns a map derived from
            the element node supplied in <code nobreak="false">$element</code>. The map is in a form
            that is suitable for JSON serialization, thus providing a mechanism for conversion
            of arbitrary XML to JSON.</p><p>The map that is returned will always be a <termref def="dt-single-entry-map"/>;
         the key of this entry will be a string representing the element name, and the value of the
         entry will be a representation of the element's attributes and children.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows.
         The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="plan" type="map( xs:string,&#xA;     ( fn:element-conversion-plan-record | fn:attribute-conversion-plan-record )&#xA;   )  " occur="opt"/><arg name="attribute-marker" type="xs:string" occur="opt"/><arg name="name-format" type="xs:string" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">plan?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">A conversion plan, supplied as a map whose keys represent element
                  and attribute names. The plan might be generated using the function
                  <function>element-to-map-plan</function>, or it might be constructed
                  in some other way. The format of the plan is described in <specref ref="id-creating-a-conversion-plan"/>.
               <ulist><item><p><term>Type: </term><code nobreak="false">map( xs:string,
     ( fn:element-conversion-plan-record | fn:attribute-conversion-plan-record )
   )  </code></p></item><item><p><term>Default: </term><code nobreak="false">{}</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">attribute-marker?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">A string that is prepended to any key value in the output that represents
               an XDM attribute node in the input. The string may be empty. If, after applying the requested
               prefix (or no prefix) there is a conflict between the names of attributes and child elements,
               then the requested prefix (or lack thereof) is ignored and the default prefix <code nobreak="false">"@"</code>
               is used.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">"@"</code></p></item></ulist></td></tr><tr><td rowspan="5" colspan="1"><p><code nobreak="false">name-format?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Indicates how the names of element and attribute nodes are handled.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">"default"</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">lexical</code></td><td rowspan="1" colspan="1">Names are output in the form produced by the <function>fn:name</function> function.</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">local</code></td><td rowspan="1" colspan="1">Names are output in the form produced by the <function>fn:local-name</function> function.</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">eqname</code></td><td rowspan="1" colspan="1">Names in a namespace are output in the form <code nobreak="false">"Q{uri}local"</code>.
                  Names in no namespace are output using the local name alone.</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">default</code></td><td rowspan="1" colspan="1">An element name is output as a local name alone if either (a) it is
                     a top-level element and is in no namespace, or (b) it is in the same namespace as its
                     parent element. An attribute name is output as a local name alone if it is in no namespace.
                     All other names are output in the format <code nobreak="false">"Q{uri}local"</code> if in a namespace, 
                     or <code nobreak="false">"Q{}local"</code> if in no namespace. "Top-level" here means that the element
                     is one that appears explicitly in the sequence of elements passed in the <code nobreak="false">$elements</code> argument,
                     as distinct from a descendant of such an element.</td></tr></tbody></table><p>If <code nobreak="false">$element</code> is the empty sequence, the result is the empty sequence.</p><p>The principles for conversion from elements to maps are described
            in <specref ref="id-element-layouts"/>, and the rules for selecting
         an element layout for each element are given in 
            <specref ref="id-selecting-element-layout"/>.</p><p>In general, every descendant element within the tree rooted at the supplied
            <code nobreak="false">$element</code> maps to a key-value pair in which the key represents the element name, and the
         corresponding value represents the attributes and children of the element. This key-value pair will be added 
         to the content representing its parent element, in a way that depends on the parent element's layout.</p><p>The representation of a node of any other kind depends on the layout chosen for its parent element.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error <errorref class="JS" code="0008"/> occurs if any element cannot
            be processed using the selected layout for that element, unless fallback processing
            is defined; or if error action is explicitly requested for an element.</p><p>Any error in the conversion plan is treated as a type error <xerrorref spec="XP" class="TY" code="0004"/> whether or not it is technically
            a contravention of the defined type for the value. This relieves users and implementers
            of the burden of distinguishing different kinds of error in the plan.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">element-to-map(())</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">element-to-map(&lt;foo&gt;bar&lt;/foo&gt;)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "foo": "bar" }</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">element-to-map(
    &lt;list&gt;
      &lt;item value='1'/&gt;
      &lt;item value='2'/&gt;
    &lt;/list&gt;, { 'attribute-marker': '' }
  )</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "list": [ 
    { "value": "1" },
    { "value": "2" }
  ] }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">element-to-map(
    &lt;name&gt;
      &lt;first&gt;Jane&lt;/first&gt;
      &lt;last&gt;Smith&lt;/last&gt;
    &lt;/name&gt;
  )</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "name": { 
  "first": "Jane",
  "last": "Smith" 
} }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">element-to-map(
    &lt;name xmlns="http://example.ns/"&gt;
      &lt;first&gt;Jane&lt;/first&gt;
      &lt;middle&gt;Elizabeth&lt;/middle&gt;
      &lt;middle&gt;Mary&lt;/middle&gt;
      &lt;last&gt;Smith&lt;/last&gt;
    &lt;/name&gt;, 
    { 'plan': {'Q{http://example.ns/}name': { 'layout': 'record' }},
      'name-format' : 'local'
    }
  )</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "name": { 
    "first": "Jane",
    "middle": ["Elizabeth", "Mary"],
    "last": "Smith" 
  } 
}</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">element-to-map(
    &lt;name xmlns="http://example.ns/"&gt;
      &lt;first&gt;Jane&lt;/first&gt;
      &lt;middle&gt;Elizabeth&lt;/middle&gt;
      &lt;middle&gt;Mary&lt;/middle&gt;
      &lt;last&gt;Smith&lt;/last&gt;
    &lt;/name&gt;, 
    { 'plan': {'Q{http://example.ns/}name': { 'layout': 'record' },
               'Q{http://example.ns/}middle': { 'layout': 'deep-skip' }
              },
      'name-format' : 'local'
    }
  )</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "name": { 
    "first": "Jane",
    "last": "Smith" 
  } 
}</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="map-operations"><head>Other operations on maps </head><p><emph>This section is non-normative.</emph></p><p>Because a map is a function item, functions that apply to functions also apply
               to maps. A map is an anonymous function, so <function>fn:function-name</function> returns the empty
               sequence; <function>fn:function-arity</function> always returns <code nobreak="false">1</code>.</p><p>Maps may be compared using the <function>fn:deep-equal</function> function.</p><p>There is no function or operator to atomize a map or convert it to a string (other than <function>fn:serialize</function>,
               which can be used to serialize some maps as JSON texts).</p><p>XPath 4.0 defines a number of syntactic constructs that operate on maps. These all have equivalents
            in the function library:</p><ulist><item><p>The expression <code nobreak="false">{}</code> creates the empty map 
                  (see <xspecref spec="XP40" ref="id-map-constructors"/>). This is equivalent to the
               effect of the data model primitive <code nobreak="false">dm:empty-map()</code>. Using user-visible functions
               the same can be achieved by calling <function>map:build</function> 
               or <function>map:merge</function>, supplying the empty sequence as the argument.</p></item><item><p>The map constructor <code nobreak="false">{ <var>K1</var> : <var>V1</var>, <var>K2</var> : <var>V2</var>, 
                  ... , <var>K/n</var> : <var>V/n</var> }</code> is equivalent to 
                  <code nobreak="false">map:merge((map:entry(<var>K1</var>, <var>V1</var>), map:entry(<var>K1</var>, <var>V1</var>), ..., map:entry(<var>K/n</var>, <var>V/n</var>)), { "duplicates": "reject" })</code></p></item><item><p>The lookup expression <code nobreak="false">$map?*</code> 
                  (see <xspecref spec="XP40" ref="id-lookup"/>) is equivalent to <code nobreak="false">map:items($map)</code>.</p></item><item><p>The lookup expression <code nobreak="false">$map?K</code>, where <var>K</var> is a key value, is equivalent to
               <code nobreak="false">map:get($map, <var>K</var>)</code></p></item><item><p>The expression <code nobreak="false">for key $k value $v in $map return <var>EXPR</var></code> 
                  (see <xspecref spec="XQ40" ref="id-xquery-for-clause"/> and 
                  <xspecref spec="XP40" ref="id-for-expressions"/>) 
                  is equivalent to the function
               call <code nobreak="false">map:for-each($map, fn($k, $v) { <var>EXPR</var> })</code>.</p></item><item><p>Maps can be filtered using the construct <code nobreak="false">$map?[<var>predicate</var>]</code>
               (see <xspecref spec="XP40" ref="id-filter-maps-and-arrays"/>).</p></item></ulist></div2></div1><div1 id="arrays"><head>Processing arrays</head><p>Arrays were introduced as a new datatype in XDM 3.1. This section describes functions that
            operate on arrays.</p><p>An array is an additional kind of item. An array of size <var>N</var> is a mapping from the integers
            (1 to <var>N</var>) to a set of values, called the members of the array, each of which is an arbitrary
            sequence. Because an array is an item, and therefore a sequence, arrays can be nested.</p><p>An array acts as a function from integer positions to associated values, so the
            function call <code nobreak="false">$array($index)</code> can be used to retrieve the array member at a given position.
            The function corresponding to the array has the signature 
            <code nobreak="false">function($index as xs:integer) as item()*</code>. 
            The fact that an array 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.</p><div2 id="formal-specification-of-arrays"><head>Formal Specification of Arrays</head><p>The XDM data model (<bibref ref="xpath-datamodel-40"/>) defines three primitive operations on arrays:</p><ulist><item><p><code nobreak="false">dm:empty-array</code> constructs the empty array.</p></item><item><p><code nobreak="false">dm:array-append</code> adds a member to an array.</p></item><item><p><code nobreak="false">dm:iterate-array</code> applies a supplied function to every member of an array, in order.</p></item></ulist><p>The functions in this section are all specified by means of equivalent expressions that either call
            these primitives directly, or invoke other functions that rely on these primitives. The specifications
            avoid relying on XPath language constructs that manipulate arrays, such as array constructor syntax, lookup
            expressions, or FLWOR expressions. This is done to allow these language constructs
            to be specified by reference to this function library, without risk of circularity.</p><p>There is one exception to this rule: for convenience, the notation <code nobreak="false">[]</code> is used to represent
            the empty array, in preference to a call on <code nobreak="false">dm:empty-array()</code>.</p><p>The formal equivalents are not intended to provide a realistic way of implementating the
            functions. They do, however, provide a framework that allows
            the correctness of a practical implementation to be verified.</p></div2><div2 id="array-functions"><head>Functions that operate on arrays</head><p>The functions defined in this section use a conventional namespace prefix <code nobreak="false">array</code>, which
               is assumed to be bound to the namespace URI <code nobreak="false">http://www.w3.org/2005/xpath-functions/array</code>.</p><p>As with all other values, arrays are treated as immutable. 
               For example, the <function>array:reverse</function> function returns an array that differs from the supplied
               array in the order of its members, but the supplied array is not changed by the operation. Two calls
               on <function>array:reverse</function> with the same argument will return arrays that are indistinguishable from
               each other; there is no way of asking whether these are “the same array”. Like sequences, arrays have no identity. </p><p diff="chg" at="2023-02-20">All functionality on arrays is defined in terms of two primitives:</p><ulist diff="chg" at="2023-02-20"><item><p>The function <function>array:members</function> decomposes an array to a sequence of 
                  <term>value records</term>.</p></item><item><p>The function <function>array:of-members</function> composes an array from a sequence of 
               <term>value records</term>.</p></item></ulist><p diff="chg" at="2023-02-20">A <term>value record</term> here is an item that encapsulates an arbitrary value; the representation
            chosen for a value record is <code nobreak="false">record(value as item()*)</code>, that is, a map containing a single
            entry whose key is the string <code nobreak="false">"value"</code> and whose value is the encapsulated sequence.</p><p>Note that when the required type of an argument to a function such as <function>array:build</function>
            is an array type, then the coercion rules ensure that a JNode can be supplied in the function call:
            if the <term>·jvalue·</term> property of the JNode is an array, then the array is automatically
            extracted as if by the <function>jvalue</function> function.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:append</code></td><td rowspan="1" colspan="1">Returns an array containing all the members of a supplied array, plus one additional member at the end.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:build</code></td><td rowspan="1" colspan="1">Returns an array obtained by evaluating the supplied function once for each item in the input sequence.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:empty</code></td><td rowspan="1" colspan="1">Returns <code nobreak="false">true</code> if the supplied array contains no members.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:filter</code></td><td rowspan="1" colspan="1">Returns an array containing those members of the <code nobreak="false">$array</code> for which 
            <code nobreak="false">$predicate</code> returns <code nobreak="false">true</code>. A return value of <code nobreak="false">()</code>
         is treated as <code nobreak="false">false</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:flatten</code></td><td rowspan="1" colspan="1">Replaces any array appearing in a supplied sequence with the members of the array, recursively.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:fold-left</code></td><td rowspan="1" colspan="1">Evaluates the supplied function cumulatively on successive members of the supplied
            array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:fold-right</code></td><td rowspan="1" colspan="1">Evaluates the supplied function cumulatively on successive values of the supplied
            array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:foot</code></td><td rowspan="1" colspan="1">Returns the last member of an array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:for-each</code></td><td rowspan="1" colspan="1">Returns an array whose size is the same as <code nobreak="false">array:size($array)</code>, in which
            each member is computed by applying <code nobreak="false">$action</code> to the corresponding member of
            <code nobreak="false">$array</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:for-each-pair</code></td><td rowspan="1" colspan="1">Returns an array obtained by evaluating the supplied function once for each pair of members at the same position in
            the two supplied arrays.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:get</code></td><td rowspan="1" colspan="1">Returns the value at the specified position in the supplied array
            (counting from 1).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:head</code></td><td rowspan="1" colspan="1">Returns the first member of an array, that is <code nobreak="false">$array(1)</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:index-of</code></td><td rowspan="1" colspan="1">Returns a sequence of positive integers giving the positions within the array
               <code nobreak="false">$array</code> of members that are equal to <code nobreak="false">$target</code>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:index-where</code></td><td rowspan="1" colspan="1">Returns the positions in an input array of members that match a supplied predicate.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:insert-before</code></td><td rowspan="1" colspan="1">Returns an array containing all the members of the supplied array, with one additional member at a specified position.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:items</code></td><td rowspan="1" colspan="1">Returns the sequence concatenation of the members of an array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:join</code></td><td rowspan="1" colspan="1">Concatenates the contents of several arrays into a single array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:members</code></td><td rowspan="1" colspan="1">Delivers the contents of an array as a sequence of <term>value records</term>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:of-members</code></td><td rowspan="1" colspan="1">Constructs an array from the contents of a sequence of <term>value records</term>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:put</code></td><td rowspan="1" colspan="1">Returns an array containing all the members of a supplied array, except for one member which is replaced with a new value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:remove</code></td><td rowspan="1" colspan="1">Returns an array containing all the members of the supplied array, except for the 
            members at specified positions.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:reverse</code></td><td rowspan="1" colspan="1">Returns an array containing all the members of a supplied array, but in reverse order.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:size</code></td><td rowspan="1" colspan="1">Returns the number of members in the supplied array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:slice</code></td><td rowspan="1" colspan="1">Returns an array containing selected members of a supplied input array based on their position.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:sort</code></td><td rowspan="1" colspan="1">Sorts a supplied array, based on the value of a sort key supplied as a function.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:sort-by</code></td><td rowspan="1" colspan="1">Sorts a supplied array, based on the value of a number of sort keys supplied as functions.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:sort-with</code></td><td rowspan="1" colspan="1">Sorts a supplied array, according to the order induced by the supplied comparator
            functions.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:split</code></td><td rowspan="1" colspan="1">Delivers the contents of an array as a sequence of single-member arrays.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:subarray</code></td><td rowspan="1" colspan="1">Returns an array containing all members from a supplied array starting at a supplied
            position, up to a specified length.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:tail</code></td><td rowspan="1" colspan="1">Returns an array containing all members except the first from a supplied array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">array:trunk</code></td><td rowspan="1" colspan="1">Returns an array containing all members except the last from a supplied array.</td></tr></tbody></table><div3 id="func-array-append"><head>array:append</head><glist><gitem><label>Summary</label><def><p>Returns an array containing all the members of a supplied array, plus one additional member at the end.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="append" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="member" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the result is an array whose size is <code nobreak="false">array:size($array) + 1</code>, in which all
            members in positions 1 to <code nobreak="false">array:size($array)</code> are the same as the members in the corresponding position
            of <code nobreak="false">$array</code>, and the member in position <code nobreak="false">array:size($array) + 1</code> is <code nobreak="false">$member</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function is defined as follows, making use of primitive constructors and accessors defined
		in <bibref ref="xpath-datamodel-40"/>.</p><eg xml:space="preserve">dm:array-append($array, $member)</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:append([ "a", "b", "c" ], "d")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:append([ "a", "b", "c" ], ("d", "e"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c", ("d", "e") ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:append([ "a", "b", "c" ], [ "d", "e" ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c", [ "d", "e" ] ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-build" diff="chg" at="2023-02-20"><head>array:build</head><changes><change issue="97" PR="250" date="2022-12-07">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns an array obtained by evaluating the supplied function once for each item in the input sequence.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="build" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="action" type="(fn(item(), xs:integer) as item()*)?" default="fn:identity#1" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the  function applies the function to each item 
            in the input sequence, and the resulting sequence becomes one member of the returned array.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:of-members(
  for-each($input, 
    fn($item, $pos) { { 'value': $action($item, $pos) } }
  )
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>The single-argument function <code nobreak="false">array:build($input)</code> is equivalent to the XPath
         expression <code nobreak="false">array { $input }</code>, but it is useful to have this available as a function.</p><p>The two-argument form facilitates the construction of arrays whose members are arbitrary
         sequences.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:build(1 to 5)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 1, 2, 3, 4, 5 ]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:build(1 to 5, fn { 2 * . })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 2, 4, 6, 8, 10 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:build(1 to 5, fn { 1 to . })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, (1, 2), (1, 2, 3), (1, 2, 3, 4), (1, 2, 3, 4, 5) ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:build(("red", "green", "blue"), characters#1)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ ("r", "e", "d"), ("g", "r", "e", "e", "n"), ("b", "l", "u", "e") ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:build(1 to 5, fn { array { 1 to . } })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ [ 1 ], [ 1, 2 ], [ 1, 2, 3 ], [ 1, 2, 3, 4 ], [ 1, 2, 3, 4, 5 ] ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
array:build(
  (0x41 to 0x48) ! char(.),
  fn($char, $pos) {
    if ($pos mod 2 = 0) then lower-case($char) else $char
  }
)
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "A", "b", "C", "d", "E", "f", "G", "h" ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-empty" diff="add" at="2022-12-06"><head>array:empty</head><changes><change>New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns <code nobreak="false">true</code> if the supplied array contains no members.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="empty" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns <code nobreak="false">true</code> if and only if <code nobreak="false">$array</code> contains no members.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:size($array) eq 0</eg></def></gitem><gitem><label>Notes</label><def><note><p>The test for emptiness is not the same as the test used by the
            <code nobreak="false">xsl:on-empty</code> instruction in XSLT. For example, an array 
            is not considered empty by this function if it contains a single
            member that is itself the empty array.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:empty([ "a", "b", "c" ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:empty([])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:empty([ [] ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:empty([ () ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">false()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-filter"><head>array:filter</head><changes><change issue="516" PR="828" date="2023-11-14">The <code nobreak="false">$predicate</code> callback function now accepts an optional position argument.</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Returns an array containing those members of the <code nobreak="false">$array</code> for which 
            <code nobreak="false">$predicate</code> returns <code nobreak="false">true</code>. A return value of <code nobreak="false">()</code>
         is treated as <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="filter" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="predicate" type="fn(item()*, xs:integer) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function returns an array containing those members of the input
         array that satisfy the supplied predicate.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XQuery expression.</p><eg xml:space="preserve">array:of-members(
  filter(
    array:members($array),
    fn($item, $pos) { $predicate(map:get($item, 'value'), $pos) }
  )
)</eg></def></gitem><gitem><label>Error Conditions</label><def><p>As a consequence of the function signature and the function calling rules, a type error occurs if the supplied
            function <code nobreak="false">$function</code> returns anything other than a single <code nobreak="false">xs:boolean</code> item
            or the empty sequence; there is no conversion to an effective boolean value.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:filter(
  [ "A", "B", 1, 2 ],
  fn($x) { $x instance of xs:integer }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, 2 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:filter(
  [ "the cat", "sat", "on the mat" ],
  function { count(tokenize(.)) &gt; 1 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "the cat", "on the mat" ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:filter([ "A", "B", "", 0, 1 ], boolean#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "A", "B", 1] </code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $array := [ 1, 1, 2, 3, 4, 4, 5 ]
return array:filter(
  $array,
  fn($item, $pos) { $pos &gt; 1 and $item = $array($pos - 1) }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, 4 ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-flatten"><head>array:flatten</head><glist><gitem><label>Summary</label><def><p>Replaces any array appearing in a supplied sequence with the members of the array, recursively.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="flatten" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function processes the items in the supplied sequence <code nobreak="false">$input</code> as follows:</p><ulist><item><p>An item that is an array is replaced by its members, retaining order.</p></item><item><p>Any other item is retained unchanged.</p></item></ulist><p>The process is then repeated so long as the sequence contains an array among its items.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function delivers the same result as the following XQuery implementation.</p><eg xml:space="preserve">declare function array:flatten(
  $input as item()*
) as item()* {
  for $item in $input
  return (
    if ($item instance of array(*)) 
    then array:flatten(array:items($item)) 
    else $item
  )
};</eg></def></gitem><gitem><label>Notes</label><def><note><p>The argument to the function will often be a single array item, but this is not essential.</p><p>Unlike atomization, this function retains any nodes contained in the array.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:flatten([ 1, 4, 6, 5, 3 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 4, 6, 5, 3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:flatten(([ 1, 2 ], [ [ 10, 11 ], 12 ], [], 13))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2, 10, 11, 12, 13</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:flatten([ (1, 0), (1, 1), (0, 1), (0, 0) ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 0, 1, 1, 0, 1, 0, 0</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-fold-left"><head>array:fold-left</head><glist><gitem><label>Summary</label><def><p>Evaluates the supplied function cumulatively on successive members of the supplied
            array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="fold-left" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="init" type="item()*"/><arg name="action" type="fn(item()*, item()*) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function is defined formally below, in terms of the equivalent <function>fn:fold-left</function>
            function for sequences.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">fold-left(
  array:members($array),
  $init,
  fn($result, $member) { $action($result, map:get($member, 'value')) }
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>If the supplied array is empty, the function returns <code nobreak="false">$init</code>.</p><p>If the supplied array contains a single member <code nobreak="false">$m</code>, the function returns <code nobreak="false">$init =&gt; $action($m)</code>.</p><p>If the supplied array contains two members <code nobreak="false">$m</code> and <code nobreak="false">$n</code>, the function returns 
            <code nobreak="false">$init =&gt; $action($m) =&gt; $action($n)</code>; and similarly for an input array with more than two members.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:fold-left(
  [ true(), true(), false() ],
  true(),
  fn($x, $y) { $x and $y }
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg><p><emph>(Returns <code nobreak="false">true</code> if every member of the input array has an effective boolean value of <code nobreak="false">true</code>.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:fold-left(
  [ true(), true(), false() ],
  false(), 
  fn($x, $y) { $x or $y }
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(Returns <code nobreak="false">true</code> if at least one member of the input array has an effective boolean value of <code nobreak="false">true</code>.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:fold-left(
  [ 1, 2, 3 ],
  [],
  fn($x, $y) { [ $x, $y ] }
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ [ [ [], 1 ], 2 ], 3 ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-fold-right"><head>array:fold-right</head><glist><gitem><label>Summary</label><def><p>Evaluates the supplied function cumulatively on successive values of the supplied
            array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="fold-right" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="init" type="item()*"/><arg name="action" type="fn(item()*, item()*) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function is defined formally below, in terms of the equivalent <function>fn:fold-right</function>
            function for sequences.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">fold-right(
  array:members($array),
  $init,
  fn($member, $result) { $action(map:get($member, 'value'), $result) }
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>If the supplied array is empty, the function returns <code nobreak="false">$init</code>.</p><p>If the supplied array contains a single member <code nobreak="false">$m</code>, the function returns <code nobreak="false">$action($m, $init)</code>.</p><p>If the supplied array contains two members <code nobreak="false">$m</code> and <code nobreak="false">$n</code>, the function returns 
            <code nobreak="false">$action($m, $action($n, $init))</code>; and similarly for an input array with more than two members.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:fold-right(
  [ true(), true(), false() ],
  true(),
  fn($x, $y) { $x and $y }
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg><p><emph>(Returns <code nobreak="false">true</code> if every member of the input array has an effective boolean value of <code nobreak="false">true</code>.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:fold-right(
  [ true(), true(), false() ],
  false(),
  fn($x, $y) { $x or $y }
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(Returns <code nobreak="false">true</code> if at least one member of the input array has an effective boolean value of <code nobreak="false">true</code>.)</emph></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:fold-right(
  [ 1, 2, 3 ],
  [],
  fn($x, $y) { [ $x, $y ] }
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, [ 2, [ 3, [] ] ] ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-foot" diff="add" at="2022-11-16"><head>array:foot</head><changes><change issue="97" PR="250" date="2022-12-07">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the last member of an array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="foot" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the last member of <code nobreak="false">$array</code>.
            </p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:get($array, array:size($array))</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code nobreak="false">$array</code> is empty.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:foot([ 5, 6, 7, 8 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">8</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:foot([ [ "a", "b" ], [ "c", "d" ] ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:foot([ ("a", "b"), ("c", "d") ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"c", "d"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-for-each"><head>array:for-each</head><changes><change issue="516" PR="828" date="2023-11-14">The <code nobreak="false">$action</code> callback function now accepts an optional position argument.</change></changes><glist><gitem><label>Summary</label><def><p>Returns an array whose size is the same as <code nobreak="false">array:size($array)</code>, in which
            each member is computed by applying <code nobreak="false">$action</code> to the corresponding member of
            <code nobreak="false">$array</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="for-each" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="action" type="fn(item()*, xs:integer) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function returns an array whose members are obtained by applying 
         the supplied <code nobreak="false">$action</code> function to each member of the input array in turn.</p><p>The <code nobreak="false">$action</code> function is called with two arguments: the first is the
         array member (which in general is an arbitrary sequence), and the second is the 1-based
         integer position.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:of-members(
  for-each(array:members($array), 
           fn($member, $pos) {
              { 'value': $action(map:get($member, 'value'), $pos) }
           })
)</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:for-each(
  [ "A", "B", 1, 2 ],
  fn($z) { $z instance of xs:integer }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[false(), false(), true(), true()]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:for-each(
  [ "the cat", "sat", "on the mat" ],
  tokenize#1
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ ("the", "cat"), "sat", ("on", "the", "mat") ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:for-each(
  [ [ "the", "cat" ], [ "sat" ], [ "on", "the", "mat" ] ],
  array:flatten#1
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ ("the", "cat"), "sat", ("on", "the", "mat") ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:for-each(
  [ 'one', 'two', 'three' ],
  fn($member, $pos) { $pos || '. ' || $member }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "1. one", "2. two", "3. three" ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-for-each-pair"><head>array:for-each-pair</head><changes><change issue="516" PR="828" date="2023-11-14">The <code nobreak="false">$action</code> callback function now accepts an optional position argument.</change></changes><glist><gitem><label>Summary</label><def><p>Returns an array obtained by evaluating the supplied function once for each pair of members at the same position in
            the two supplied arrays.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="for-each-pair" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array1" type="array(*)"/><arg name="array2" type="array(*)"/><arg name="action" type="fn(item()*, item()*, xs:integer) as item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function applies <code nobreak="false">$action</code> to each pair of values in corresponding positions
            within <code nobreak="false">$array1</code> and <code nobreak="false">$array2</code>, ignoring any excess values if one array is longer
            than the other. The results are then assembed into a new array whose size is equal to the shorter of the
            two input arrays.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:of-members(
  for-each-pair(
    array:members($array1),
    array:members($array2),
    fn($v1, $v2, $pos) {
      { 'value': $action(map:get($v1, 'value'), map:get($v2, 'value'), $pos) }
    }
  )
)</eg></def></gitem><gitem><label>Notes</label><def><note><p>If the arrays have different size, excess members in the longer array are ignored.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:for-each-pair(
  [ "A", "B", "C" ],
  [ 1, 2, 3 ],
  fn($x, $y) { array { $x, $y }}
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ [ "A", 1 ], [ "B", 2 ], [ "C", 3 ] ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $array := [ "A", "B", "C", "D" ]
return array:for-each-pair(
  $array,
  array:tail($array),
  concat#2
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "AB", "BC", "CD" ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
array:for-each-pair(
  [ 1, 8, 2 ],
  [ 3, 4, 3 ],
  fn($member1, $member2, $pos) {
    $pos || ': ' || max(($member1, $member2))
  }
)
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "1: 3", "2: 8", "3: 3" ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-get"><head>array:get</head><changes><change issue="1363" PR="289 1901">A third argument is added, allowing user control of how index-out-of-bounds
            conditions should be handled.</change></changes><glist><gitem><label>Summary</label><def><p>Returns the value at the specified position in the supplied array
            (counting from 1).</p></def></gitem><gitem><label>Signatures</label><def><example role="signature"><proto isOp="no" prefix="array" name="get" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="position" type="xs:integer"/></proto></example><example role="signature"><proto isOp="no" prefix="array" name="get" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="position" type="xs:integer"/><arg name="default" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p diff="chg" at="2022-12-16">Informally, the function returns the member at a specified position in the array.</p><p>If <code nobreak="false">$position</code> is out of bounds (that is, if
         it is less than one or greater than <code nobreak="false">array:size($array)</code>), then the effect 
            depends on the number of arguments:</p><ulist><item><p>When there are two arguments, an error is raised (<errorref class="AY" code="0001"/>).</p></item><item><p>When there are three arguments, the value of <code nobreak="false">$default</code> is returned.</p></item></ulist><ednote><edtext>Provide separate "formal equivalents" for the two variants.</edtext></ednote></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression, except in error cases.</p><eg xml:space="preserve">(: For the two-argument form: :)           
    if ($position = (1 to array:size($array)))
    then items-at(array:members($array), $position) =&gt; map:get('value'))
    else error(),
(: For the three-argument form: :)           
    if ($position = (1 to array:size($array)))
    then items-at(array:members($array), $position) =&gt; map:get('value'))
    else $default</eg></def></gitem><gitem><label>Error Conditions</label><def><p>In the absence of a <code nobreak="false">$default</code> argument,
            a dynamic error occurs <errorref class="AY" code="0001"/> if <code nobreak="false">$position</code> is not in the range <code nobreak="false">1 to
               array:size($array)</code> inclusive.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">[ "a", "b", "c" ] =&gt; array:get(2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"b"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">[ "a", [ "b", "c" ] ] =&gt; array:get(2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">[ "a" ] =&gt; array:get(1, ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">[ "a" ] =&gt; array:get(2, ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-head"><head>array:head</head><glist><gitem><label>Summary</label><def><p>Returns the first member of an array, that is <code nobreak="false">$array(1)</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="head" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns first member of <code nobreak="false">$array</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:get($array, 1)</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code nobreak="false">$array</code> is empty.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:head([ 5, 6, 7, 8 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">5</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:head([ [ "a", "b" ], [ "c", "d" ] ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:head([ ("a", "b"), ("c", "d") ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"a", "b"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-index-of"><head>array:index-of</head><changes><change issue="260 1096" PR="968 1295" date="2024-02-06">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a sequence of positive integers giving the positions within the array
               <code nobreak="false">$array</code> of members that are equal to <code nobreak="false">$target</code>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="index-of" return-type="xs:integer*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="target" type="item()*"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>The two-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and implicit timezone.
	</p><p>The three-argument form of this function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations, and static base URI, and implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>Informally, all members of <code nobreak="false">$array</code> are compared with <code nobreak="false">$target</code>.
            An array member is compared to the target value using the rules of the
            <function>fn:deep-equal</function> function, with the specified (or defaulted) collation.
            The index position of the member is included in the result sequence if the
            comparison returns true.
         </p><p>The collation used by this function is determined according to the rules in <specref ref="choosing-a-collation"/>. This collation is used when string comparison is required.</p><p>The first member in an array is at position 1, not position 0.</p><p>The result sequence is in ascending numeric order.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:index-where($array, deep-equal(?, $target, $collation))</eg></def></gitem><gitem><label>Notes</label><def><note><p>If <code nobreak="false">$array</code> is the empty array, or if no member in
            <code nobreak="false">$array</code> matches <code nobreak="false">$target</code>, then the function returns the empty
            sequence.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:index-of([ 10, 20, 30, 30, 20, 10 ], 20)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2, 5</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:index-of([ (), 1, (5, 6), (6, 7) ], (6, 7))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">4</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
array:index-of(
  [ "a", ("b", "C"), "d" ],
  ("B", "c"),
  "http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"
)
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
array:index-of(
  [ '1', xs:untypedAtomic('1'), 1, current-date() ],
  '1'
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 2</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-index-where" diff="add" at="2022-11-17"><head>array:index-where</head><changes><change issue="114" PR="258" date="2022-12-13">New in 4.0</change><change issue="1171" PR="1182" date="2024-05-07">The <code nobreak="false">$predicate</code> callback function may return the empty sequence (meaning <code nobreak="false">false</code>).</change></changes><glist><gitem><label>Summary</label><def><p>Returns the positions in an input array of members that match a supplied predicate.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="index-where" return-type="xs:integer*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="predicate" type="fn(item()*, xs:integer) as xs:boolean?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The result of the function is a sequence of integers, in monotonic ascending order, representing
            the 1-based positions in the input array of those members for which the supplied predicate function
            returns <code nobreak="false">true</code>. A return value of <code nobreak="false">()</code> is treated as <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">dm:iterate-array($array, fn($member, $pos) {
  if ($predicate($member, $pos)) { $pos }
})</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:index-where([], boolean#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:index-where([ 0, (), 4, 9 ], boolean#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3, 4</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:index-where(
  array { 1 to 10 },
  function { . mod 2 = 0 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2, 4, 6, 8, 10</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:index-where(
  [ "January", "February", "March", "April",
    "May", "June", "July", "August", "September",
    "October", "November", "December" ],
  contains(?, "r")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 2, 3, 4, 9, 10, 11, 12</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:index-where(
  [ (1, 2, 3), (4, 5, 6), (7, 8) ],
  fn($m) { count($m) = 3 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 2</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:index-where(
  [ 1, 8, 2, 7, 3 ],
  fn($member, $pos) { $member &lt; 5 and $pos &gt; 2 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">3, 5</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-insert-before"><head>array:insert-before</head><glist><gitem><label>Summary</label><def><p>Returns an array containing all the members of the supplied array, with one additional member at a specified position.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="insert-before" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="position" type="xs:integer"/><arg name="member" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function returns an array of size <code nobreak="false">array:size($array) + 1</code>
            containing all members from <code nobreak="false">$array</code>
            whose position is less than <code nobreak="false">$position</code>, then a new member given by <code nobreak="false">$member</code>, and
            then all members from <code nobreak="false">$array</code> whose position is greater than or equal to <code nobreak="false">$position</code>. 
            Positions are counted from 1.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression, except in error cases.</p><eg xml:space="preserve">$array 
=&gt; array:members() 
=&gt; insert-before($position, { 'value': $member })
=&gt; array:of-members()</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code nobreak="false">$position</code> is not in the range <code nobreak="false">1 to
            array:size($array) + 1</code> inclusive.</p></def></gitem><gitem><label>Notes</label><def><note><p>Setting <code nobreak="false">$position</code> to 1 has the effect of prepending the new member at the start of the array. Setting <code nobreak="false">$position</code>
         to the value <code nobreak="false">array:size($array) + 1</code> delivers the same result as <code nobreak="false">array:append($array, $member)</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:insert-before(
  [ "a", "b", "c", "d" ],
  3,
  ("x", "y")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "a", "b", ("x", "y"), "c", "d" ]</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:insert-before(
  [ "a", "b", "c", "d" ],
  5,
  ("x", "y")
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "a", "b", "c", "d", ("x", "y") ]</eg></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:insert-before(
  [ "a", "b", "c", "d" ],
  3,
  [ "x", "y" ]
)</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "a", "b", [ "x", "y" ], "c", "d" ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-items" diff="add" at="2023-05-07"><head>array:items</head><changes><change issue="29 1086" PR="476 1087" date="2023-09-05">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the sequence concatenation of the members of an array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="items" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the <xtermref spec="XP40" ref="dt-sequence-concatenation">sequence concatenation</xtermref> 
            of the members of <code nobreak="false">$array</code>, retaining order.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">dm:iterate-array($array, fn($member, $pos) { $member })</eg></def></gitem><gitem><label>Notes</label><def><note><p>Unlike <function>array:flatten</function>, the function does not apply recursively
         to nested arrays.</p><p>If <code nobreak="false">$A</code> is a single array item, then <code nobreak="false">array:items($A)</code>
         returns the same result as <code nobreak="false">$A?*</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:items(["one", "two", "three"])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"one", "two", "three"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:items(["one", ("two", "three")])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"one", "two", "three"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:items(["one", ("two", "three"), ()])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"one", "two", "three"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:items(["one", ["two", "three"]])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"one", ["two", "three"]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:items([ (), 1, (2 to 4), [ 5 ] ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2, 3, 4, [ 5 ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-join"><head>array:join</head><glist><gitem><label>Summary</label><def><p>Concatenates the contents of several arrays into a single array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="join" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="arrays" type="array(*)*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function concatenates the members of several arrays into a single array.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">$arrays
=&gt; for-each(fn($array) { array:members($array) })
=&gt; array:of-members()</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:join(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:join([ 1, 2, 3 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 1, 2, 3 ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:join(([ "a", "b" ], [ "c" ]))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:join(([ "a", "b" ], [ "c" ], []))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:join(([ "a", "b" ], [ [ "c" ] ]))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", [ "c" ] ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array { 1 to 3 }
=&gt; array:split()
=&gt; array:join()</eg></td><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1, 2, 3 ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-members" diff="add" at="2023-02-20"><head>array:members</head><changes><change issue="29 113 314" PR="360 476">New in 4.0</change><change issue="2351">The group may remove this function, it is considered <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#at-risk" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">at risk</loc>.
            </change></changes><glist><gitem><label>Summary</label><def><p>Delivers the contents of an array as a sequence of <term>value records</term>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="members" return-type="record(value as item()*)*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The members of the array are delivered as a sequence of <term>value records</term>. 
            A value record is an item that encapsulates an arbitrary sequence <code nobreak="false">$S</code>: specifically
            it is a map comprising a single entry whose key is the <code nobreak="false">xs:string</code> value
            <code nobreak="false">"value"</code> and whose corresponding value is <code nobreak="false">$S</code>. The content encapsulated
         by a value record <code nobreak="false">$V</code> can be obtained using the expression <code nobreak="false">$V?value</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The function is defined as follows, making use of primitive constructors and accessors defined
		in <bibref ref="xpath-datamodel-40"/>.</p><eg xml:space="preserve">dm:iterate-array($array, array:member#1)</eg></def></gitem><gitem><label>Notes</label><def><note><p>This function is the inverse of <function>array:of-members</function>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:members([])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:members([ 1 to 5 ])?value</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2, 3, 4, 5</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:members([ (1, 1), (2, 4), (3, 9), (4, 16), (5, 25) ])
! sum(?value)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2, 6, 12, 20, 30</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $array := [ "any array" ]
return deep-equal(
  $array,
  array:of-members(array:members($array))
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-of-members" diff="add" at="2023-02-20"><head>array:of-members</head><changes><change issue="29 113 314" PR="360 476" date="2023-03-21">New in 4.0</change><change issue="2351">The group may remove this function, it is considered <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#at-risk" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">at risk</loc>.
            </change></changes><glist><gitem><label>Summary</label><def><p>Constructs an array from the contents of a sequence of <term>value records</term>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="of-members" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="record(value as item()*)*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The input items must be <term>value records</term>, as defined in the type signature.  
            A value record is an item that encapsulates 
            an arbitrary sequence <code nobreak="false">$S</code>: specifically
            it is a map comprising a single entry whose key is the <code nobreak="false">xs:string</code> value
            <code nobreak="false">"value"</code> and whose corresponding value is <code nobreak="false">$S</code>. The content encapsulated
            by a value record <code nobreak="false">$V</code> can be obtained using the expression <code nobreak="false">$V?value</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XQuery expression.</p><eg xml:space="preserve">fold-left($input, [], fn($array, $record) { 
  array:append($array, map:get($record, 'value'))
})</eg></def></gitem><gitem><label>Notes</label><def><note><p>This function is the inverse of <function>array:members</function>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:of-members(())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:of-members({ 'value': (1 to 5) })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ (1, 2, 3, 4, 5) ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:of-members((1 to 5) ! { 'value': . })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 1, 2, 3, 4, 5 ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:of-members((1 to 3) ! { 'value': (., . * .) })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ (1, 1), (2, 4), (3, 9) ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-put"><head>array:put</head><glist><gitem><label>Summary</label><def><p>Returns an array containing all the members of a supplied array, except for one member which is replaced with a new value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="put" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="position" type="xs:integer"/><arg name="member" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the result is an array whose size is <code nobreak="false">array:size($array)</code>, in which all
            members in positions other than <code nobreak="false">$position</code> are the same as the members in the corresponding position
            of <code nobreak="false">$array</code>, and the member in position <code nobreak="false">$position</code> is <code nobreak="false">$member</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">$array 
=&gt; array:remove($position) 
=&gt; array:insert-before($position, $member)</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code nobreak="false">$position</code> is not in the range <code nobreak="false">1 to
            array:size($array)</code> inclusive.</p><p>This error will always occur if <code nobreak="false">$array</code> is empty.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:put([ "a", "b", "c" ], 2, "d")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "d", "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:put([ "a", "b", "c" ], 2, ("d", "e"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", ("d", "e"), "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:put([ "a" ], 1, [ "d", "e" ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ [ "d", "e" ] ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-remove"><head>array:remove</head><glist><gitem><label>Summary</label><def><p>Returns an array containing all the members of the supplied array, except for the 
            members at specified positions.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="remove" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="positions" type="xs:integer*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the function returns an array of size <phrase><code nobreak="false">array:size($array) - fn:count(fn:distinct-values($positions))</code></phrase> 
            containing all members from <code nobreak="false">$array</code>
            except the members whose position (counting from 1) is present in the sequence <code nobreak="false">$positions</code>.
         The order of the remaining members is preserved.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression, except in error cases.</p><eg xml:space="preserve">$array 
=&gt; array:members() 
=&gt; remove($positions) 
=&gt; array:of-members()</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="AY" code="0001"/> if any integer in <code nobreak="false">$positions</code> is not in the range <code nobreak="false">1 to
         array:size($array)</code> inclusive. By implication, an error occurs if <code nobreak="false">$array</code> is empty, unless <code nobreak="false">$positions</code>
         is also empty.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:remove([ "a", "b", "c", "d" ], 1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:remove([ "a", "b", "c", "d" ], 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:remove([ "a" ], 1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:remove([ "a", "b", "c", "d" ], 1 to 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:remove([ "a", "b", "c", "d" ], ())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c", "d" ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-reverse"><head>array:reverse</head><glist><gitem><label>Summary</label><def><p>Returns an array containing all the members of a supplied array, but in reverse order.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="reverse" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p diff="chg" at="A">The function returns an array with the same number of members
         as <code nobreak="false">$array</code>, but in reverse order.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">$array 
=&gt; array:members() 
=&gt; reverse() 
=&gt; array:of-members()</eg></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:reverse([ "a", "b", "c", "d" ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "d", "c", "b", "a" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:reverse([ ("a", "b"), ("c", "d") ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ ("c", "d"), ("a", "b") ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:reverse([ 1 to 5 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ (1, 2, 3, 4, 5) ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:reverse([])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-size"><head>array:size</head><glist><gitem><label>Summary</label><def><p>Returns the number of members in the supplied array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="size" return-type="xs:integer" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns the number of members in the array.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">count(array:members($array))</eg></def></gitem><gitem><label>Notes</label><def><note><p>Note that because an array is an item, the <function>fn:count</function> function
            when applied to an array always returns <code nobreak="false">1</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:size([ "a", "b", "c" ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">3</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:size([ "a", [ "b", "c" ] ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">2</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:size([])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">0</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:size([ [] ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-slice" diff="add" at="A"><head>array:slice</head><changes><change issue="63" PR="477" date="2023-05-09">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns an array containing selected members of a supplied input array based on their position.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="slice" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="start" type="xs:integer?" default="0" note="default-on-empty"/><arg name="end" type="xs:integer?" default="0" note="default-on-empty"/><arg name="step" type="xs:integer?" default="0" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the array is converted to a sequence, the function <function>fn:slice</function>
         is applied to this sequence, and the resulting sequence is converted back to an array.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">$array 
=&gt; array:members() 
=&gt; slice($start, $end, $step) 
=&gt; array:of-members()</eg></def></gitem><gitem><label>Notes</label><def><note><p>Note that unlike other operations on arrays, there are no out-of-bounds errors for inappropriate
         values of <code nobreak="false">$start</code>, <code nobreak="false">$end</code>, or <code nobreak="false">$step</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $in := [ 'a', 'b', 'c', 'd', 'e' ]</eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 2, end := 4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "c", "d", "e" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, end := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 3, end := 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 4, end := 3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "d", "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 2, end := 5, step := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 5, end := 2, step := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "e", "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 2, end := 5, step := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 5, end := 2, step := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c", "d", "e" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := -1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "e" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := -3)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "c", "d", "e" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, end := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := 2, end := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := -2, end := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "d", "c", "b" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := -4, end := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := -2, end := -4)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "d", "c", "b" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := -4, end := -2, step := 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice($in, start := -2, end := -4, step := -2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "d", "b" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:slice([ "a", "b", "c", "d" ], 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "a", "b", "c", "d" ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-sort"><head>array:sort</head><glist><gitem><label>Summary</label><def><p>Sorts a supplied array, based on the value of a sort key supplied as a function.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="sort" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="collation" type="xs:string?" default="fn:default-collation()" note="default-on-empty"/><arg name="key" type="fn(item()*) as xs:anyAtomicType*" default="fn:data#1" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>This function is retained for compatibility from version 3.1 of this specification. Version 4.0
         introduces a more powerful functions, <function>array:sort-by</function>.</p><p>The function call <code nobreak="false">array:sort($array, $collation, $key)</code> is defined to have the same effect as the
         call <code nobreak="false">array:sort-by($array, { 'key': $key, 'collation': $collation, 'order': 'ascending'})</code>.
         See <function>array:sort-by</function>.</p><p>The result of the function is a sequence that contains all the items from <code nobreak="false">$input</code>,
         typically in a different order, the order being defined by the supplied sort key definitions.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:sort-by($array, { 'key': $key, 'collation': $collation, 'order': 'ascending' })</eg></def></gitem><gitem><label>Error Conditions</label><def><p>If the set of computed sort keys contains values that are not comparable using the <code nobreak="false">lt</code> operator then the sort 
            operation will fail with a type error (<xerrorref spec="XP" class="TY" code="0004"/>).
         </p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort([ 1, 4, 6, 5, 3 ])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 1, 3, 4, 5, 6 ]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort([ 1, -2, 5, 10, -10, 10, 8 ], (), abs#1)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 1, -2, 5, 8, 10, -10, 10 ]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort([ [ 2, "i" ], [ 1, "e" ], [ 2, "g" ], [ 1, "f" ] ])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ [ 1, "e" ], [ 1, "f" ], [ 2, "g" ], [ 2, "i" ] ]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-sort-by"><head>array:sort-by</head><changes><change issue="1085" PR="2001" date="2025-05-19">New in 4.0.</change></changes><glist><gitem><label>Summary</label><def><p>Sorts a supplied array, based on the value of a number of sort keys supplied as functions.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="sort-by" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="keys" type="record(key? as (fn(item()*) as xs:anyAtomicType*)?, collation? as xs:string?, order? as enum('ascending', 'descending')?)*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>The result of the function is an array that contains the same members as <code nobreak="false">$array</code>,
         typically in a different order, the order being defined by the supplied <term>sort key definitions</term>.</p><p>A <term>sort key definition</term> is a record with three parts:</p><olist><item><p><code nobreak="false">key:</code> A <term>sort key function</term>, which is applied to each member of the input sequence to
            determine a <term>sort key value</term>. If no function is supplied, the default is <code nobreak="false">fn:data#1</code>,
            which atomizes the value of the array member.</p></item><item><p><code nobreak="false">collation:</code> A <term>collation</term>, which is used when comparing <term>sort key values</term>
               that are of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>. If no collation is supplied, the default
               collation from the static context is used.</p><p>When comparing values of types other than <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>,
               the collation is ignored (but an error <rfc2119>may</rfc2119> be reported if it is
               invalid). For more information see <specref ref="choosing-a-collation"/>.</p></item><item><p><code nobreak="false">order:</code> An <term>order direction</term>, either <code nobreak="false">"ascending"</code> or
            <code nobreak="false">"descending"</code>. The default is <code nobreak="false">"ascending"</code>.</p></item></olist><p>The number of sort key definitions is determined by the number of records supplied
            in the <code nobreak="false">$keys</code> argument. If the argument is absent or empty, the default is
            a single sort key definition using the function <code nobreak="false">data#1</code>, using the default collation
            from the static context, and with order <code nobreak="false">ascending</code>.</p><p>The result of the <code nobreak="false">array:sort-by</code> function is obtained as follows:</p><olist><item><p>The result array contains the same members as <code nobreak="false">$array</code>, 
                  but generally in a different order.</p></item><item><p>The sort key definitions are established as described above.
                  The sort key definitions are in major-to-minor order. That is, the position of two
                  values <code nobreak="false">$A</code> and <code nobreak="false">$B</code> in the result sequence is determined first by the 
                  relative magnitude of their
                  primary sort key values, which are computed by evaluating the <term>sort key function</term> in the 
                  first sort key definition.
                  If those two sort key values are equal, then the position is determined by the relative magnitude
                  of their secondary sort key values, computed by evaluating the 
                  sort key function in the second sort key definition, and so on.</p></item><item><p>When a pair of corresponding sort key values of <code nobreak="false">$A</code> and <code nobreak="false">$B</code> are 
                  found to be not equal,
                  then <code nobreak="false">$A</code> precedes <code nobreak="false">$B</code> in the result sequence 
                  if both the following conditions are true, or if both conditions are false:</p><olist><item><p>The sort key value for <code nobreak="false">$A</code> is less than the sort key value for <code nobreak="false">$B</code>,
                           as defined below.</p></item><item><p>The <term>order direction</term> in the corresponding sort key definition
                        is <code nobreak="false">"ascending"</code>.</p></item></olist></item><item><p>If all the sort key values for <code nobreak="false">$A</code> and <code nobreak="false">$B</code> are pairwise equal, then 
               <code nobreak="false">$A</code> precedes <code nobreak="false">$B</code> in the result sequence if and only if
               <code nobreak="false">$A</code> precedes <code nobreak="false">$B</code> in the input sequence.</p><note><p>That is, the sort is <emph>stable</emph>.</p></note></item><item><p>Each sort key value for a given array member is obtained by applying the sort key
               function of the corresponding sort key definition to that member. The result
               of this function is in the general case a sequence of atomic items.
               Two sort key values <code nobreak="false">$a</code> and <code nobreak="false">$b</code> are compared as follows:</p><olist><item><p>Let <var>$C</var> be the collation in the corresponding
                     sort key definition.</p></item><item><p>Let <code nobreak="false">$REL</code> be the result of evaluating <code nobreak="false">op:lexicographic-compare($key($A), $key($B), $C)</code>
                     where <code nobreak="false">op:lexicographic-compare($a, $b, $C)</code> is defined as follows:</p><eg xml:space="preserve">if (empty($a) and empty($b)) then 0 
else if (empty($a)) then -1
else if (empty($b)) then +1
else let $rel = op:simple-compare(head($a), head($b), $C)
     return if ($rel eq 0)
            then op:lexicographic-compare(tail($a), tail($b), $C)
            else $rel</eg></item><item><p>Here <code nobreak="false">op:simple-compare($k1, $k2)</code> is defined as follows:</p><eg xml:space="preserve">if ($k1 instance of (xs:string | xs:anyURI | xs:untypedAtomic)
    and $k2 instance of (xs:string | xs:anyURI | xs:untypedAtomic))
then compare($k1, $k2, $C)
else if ($k1 instance of xs:numeric and $k2 instance of xs:numeric)
then compare($k1, $k2)
else if ($k1 eq $k2) then 0
else if ($k2 lt $k2) then -1
else +1</eg><note><p>This raises an error if two keys are not comparable, for example
                        if one is a string and the other is a number, or if both belong to a non-ordered
                        type such as <code nobreak="false">xs:QName</code>.</p></note></item><item><p>If <code nobreak="false">$REL</code> is zero, then the two sort key values are deemed
                     equal; if <code nobreak="false">$REL</code> is -1 then <code nobreak="false">$a</code> is deemed less than
                     <code nobreak="false">$b</code>, and if <code nobreak="false">$REL</code> is +1 then <code nobreak="false">$a</code> is deemed greater than
                     <code nobreak="false">$b</code></p></item></olist></item></olist></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">$array
=&gt; array:members()
=&gt; fn:sort-by(
  for $key-spec in ($keys otherwise {})
  return map:put($key-spec, 'key', fn($member as record(value)) as xs:anyAtomicType* {
    map:get($key-spec, 'key', fn:data#1)(map:get($member, 'value'))
  }
)
=&gt; array:of-members()</eg></def></gitem><gitem><label>Error Conditions</label><def><p>If the set of computed sort keys contains values that are not comparable using the <code nobreak="false">lt</code> operator then the sort 
            operation will fail with a type error (<xerrorref spec="XP" class="TY" code="0004"/>).
         </p></def></gitem><gitem><label>Notes</label><def><note><p>The function is a generalization of the <function>array:sort</function> function available in 3.1, 
            which is retained for compatibility. The enhancements allow multiple sort keys to be defined, each potentially with
         a different collation, and allow sorting in descending order.</p><p>If the sort key for an item evaluates to the empty sequence, the effect of the rules is that this item
            precedes any value for which the key is non-empty. This is equivalent to the effect of the XQuery option 
            <code nobreak="false">empty least</code>. The effect of the option <code nobreak="false">empty greatest</code> can be achieved by adding an
            extra sort key definition with <code nobreak="false">{'key': fn{empty(K(.)}}</code>: when comparing boolean sort keys,
            <code nobreak="false">false</code> precedes <code nobreak="false">true</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort-by([1, 4, 6, 5, 3], {})</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[1, 3, 4, 5, 6]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort-by([1, 4, 4e0, 6, 5, 3], {'order': 'descending'})</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[6, 5, 4, 4e0, 3, 1]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort-by([(1,4,3), 4, (5,6), 2], ({'key': count#1}, {}))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[2, 4, (5,6), (1,4,3)]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-sort-with"><head>array:sort-with</head><changes><change issue="2012" PR="2228" date="2025-10-03">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Sorts a supplied array, according to the order induced by the supplied comparator
            functions.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="sort-with" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="comparators" type="(fn(item()*, item()*) as xs:integer)+"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Informally, the members of the supplied <code nobreak="false">$array</code> are sorted into an
            order based on the result of evaluating the supplied <code nobreak="false">$comparators</code>. 
            The result is a sorted array.</p><p>Each comparator function takes two values and returns an <code nobreak="false">xs:integer</code> that
            defines the relationship between these values, following the conventions of the
            <function>fn:compare</function> function. Specifically, when a comparator
            <code nobreak="false">$c</code> is used to compare two values <code nobreak="false">$a</code> and <code nobreak="false">$b</code>,
            it must return a negative integer if <code nobreak="false">$a</code> is to be sorted before <code nobreak="false">$b</code>,
            zero if they are considered equal, and a positive integer if <code nobreak="false">$a</code> is
            to be sorted after <code nobreak="false">$b</code>.</p><p>There may be more than one comparator, representing sort keys in major to minor order.
         To determine the relative position of two members <code nobreak="false">$a</code> and <code nobreak="false">$b</code>:</p><olist><item><p>The first comparator is called: <code nobreak="false">$comparators[1]($a, $b)</code>. If
            the result is non-zero, this determines the relative position of <code nobreak="false">$a</code>
               and <code nobreak="false">$b</code> in the result array, and any further comparators
            can be ignored.</p></item><item><p>If the <var>N</var>th comparator returns zero, then:</p><olist><item><p>If this is the last comparator, then the two members are considered
                  equal, and their relative position in the result sequence will be the same
                  as their relative position in the input sequence (that is, the sort is
                  <emph>stable</emph>).</p></item><item><p>Otherwise, the next comparator is evaluated, and so on,
                  until the last comparator is reached or the result of a comparator is non-zero.</p></item></olist></item></olist><p>To ensure that the sorting algorithm produces predictable results (indeed, to ensure
         that it terminates), it is necessary for the comparators to have certain properties.
         Specifically, for every comparator <var>C</var>:</p><olist><item><p><var>C</var> must be deterministic (if called twice with the same arguments,
            it must deliver the same result).</p></item><item><p>Every value must be equal to itself: <code nobreak="false"><var>C</var>($a, $a)</code> must be zero.</p></item><item><p>The ordering must be consistent: if <code nobreak="false"><var>C</var>($a, $b) &lt; 0</code>,
            then <code nobreak="false"><var>C</var>($b, $a) &gt; 0</code>, and vice versa, and similarly,
            if <code nobreak="false"><var>C</var>($a, $b) = 0</code>,
            then <code nobreak="false"><var>C</var>($b, $a) = 0</code>.</p></item><item><p>The ordering must be transitive: if <code nobreak="false"><var>C</var>($a, $b) &lt; 0</code>
               and <code nobreak="false"><var>C</var>($b, $c) &lt; 0</code>, then <code nobreak="false"><var>C</var>($a, $c) &lt; 0</code>.</p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>If a comparator function raises an error when processing any pair of members from the input array
         (for example, if the comparator function is <code nobreak="false">fn:compare#2</code> and one of the members
            is not coercible to <code nobreak="false">xs:anyAtomicType</code>), then the evaluation of
            <function>fn:sort-with</function> fails with that error.</p><p>In general it is unpredictable which pairs of members from the input array
         will actually be compared using each comparator function. However, a comparator function
         <rfc2119>must</rfc2119> not be called to compare two members if they have been determined as unequal by
         an earlier comparator function.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort-with([1, 4, 6, 5, 3], compare#2)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[1, 3, 4, 5, 6]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort-with([1, 4, 6, 5, 3], op('-'))</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[1, 3, 4, 5, 6]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:sort-with([1, 4, 4e0, 6, 5, 3], fn($a, $b) { compare($b, $a) })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[6, 5, 4, 4e0, 3, 1]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:sort-with(
  [ { "a": 1, "b": 20 }, { "a": 5, "b": 12 }, { "a": 1, "b": 3 } ],
   ( fn($x, $y) { compare($x?a, $y?a) },
     fn($x, $y) { compare($x?b, $y?b) })  
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ { "a": 1, "b": 3 }, { "a": 1, "b": 20 }, { "a": 5, "b": 12 } ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-split"><head>array:split</head><changes><change issue="508" PR="609" date="2023-07-25">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Delivers the contents of an array as a sequence of single-member arrays.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="split" return-type="array(*)*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The members of the array are delivered as a sequence of 
            <xtermref spec="DM40" ref="dt-single-member-array">single-member arrays</xtermref>. 
            Each returned array encapsulates the value of one member of <code nobreak="false">$array</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">dm:iterate-array($array, fn($member) { array:append([], $member) })</eg></def></gitem><gitem><label>Notes</label><def><note><p>The function call <code nobreak="false">array:split($array)</code> produces the same result as the
            expression <code nobreak="false">for member $m in $array return [ $m ]</code>.</p><p>The expression <code nobreak="false">$A =&gt; array:split() =&gt; array:join()</code>, applied to any array
            <code nobreak="false">$A</code>, returns the original array <code nobreak="false">$A</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:split([])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:split([ () ])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ () ]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">array:split([ 1 to 5 ])</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ (1, 2, 3, 4, 5) ]</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:split(
  array { 1 to 5 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ 1 ], [ 2 ], [ 3 ], [ 4 ], [ 5 ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">array:split(
  [ (1, 1), (2, 4), (3, 9), (4, 16), (5, 25) ]
) ! sum(.)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2, 6, 12, 20, 30</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $array := [ "any array" ]
return deep-equal(
  $array,
  array:join(array:split($array))
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-subarray"><head>array:subarray</head><changes><change>Supplying the empty sequence as the value of an optional argument is equivalent to
            omitting the argument.</change></changes><glist><gitem><label>Summary</label><def><p>Returns an array containing all members from a supplied array starting at a supplied
            position, up to a specified length.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="subarray" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/><arg name="start" type="xs:integer"/><arg name="length" type="xs:integer?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Except in error cases, 
            the two-argument version of the function returns the same result as the three-argument
            version when called with <code nobreak="false">$length</code> equal to the value of
            <code nobreak="false">array:size($array) - $start + 1</code>.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression, except in error cases.</p><eg xml:space="preserve">$array
=&gt; array:members()
=&gt; subsequence($start, $length)
=&gt; array:of-members()</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="AY" code="0001"/> if <code nobreak="false">$start</code> is less than one
            <phrase>or greater than <code nobreak="false">array:size($array) + 1</code></phrase>.</p><p>For the three-argument version of the function:</p><ulist><item><p>A dynamic error is raised <errorref class="AY" code="0002"/> 
               if <code nobreak="false">$length</code> is less than zero.</p></item><item><p>A dynamic error is raised <errorref class="AY" code="0001"/> 
               if <code nobreak="false">$start + $length</code> is greater than <code nobreak="false">array:size($array) + 1</code>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>The value of <code nobreak="false">$start</code> can be equal to <code nobreak="false">array:size($array) + 1</code> provided that <code nobreak="false">$length</code>
         is either equal to zero or omitted. In this case the result will be the empty array.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:subarray([ "a", "b", "c", "d" ], 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "c", "d" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:subarray([ "a", "b", "c", "d" ], 5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:subarray([ "a", "b", "c", "d" ], 2, 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:subarray([ "a", "b", "c", "d" ], 2, 1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:subarray([ "a", "b", "c", "d" ], 2, 2)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ "b", "c" ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:subarray([ "a", "b", "c", "d" ], 5, 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:subarray([], 1, 0)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-tail"><head>array:tail</head><glist><gitem><label>Summary</label><def><p>Returns an array containing all members except the first from a supplied array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="tail" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns an array containing all members of the supplied array except the first.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:remove($array, 1)</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code nobreak="false">$array</code> is empty.</p></def></gitem><gitem><label>Notes</label><def><note><p>If the supplied array contains exactly one member, the result will be the empty array.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:tail([ 5, 6, 7, 8 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 6, 7, 8 ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:tail([ 5 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-array-trunk" diff="add" at="2022-11-16"><head>array:trunk</head><changes><change issue="97" PR="250" date="2022-12-07">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns an array containing all members except the last from a supplied array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="array" name="trunk" return-type="array(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="array" type="array(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns an array containing all members of the supplied array except the last.</p></def></gitem><gitem><label>Formal Equivalent</label><def><p>The effect of the function is equivalent to the result of the following XPath expression.</p><eg xml:space="preserve">array:remove($array, array:size($array))</eg></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error occurs <errorref class="AY" code="0001"/> if <code nobreak="false">$array</code> is empty.</p></def></gitem><gitem><label>Notes</label><def><note><p>If the supplied array contains exactly one member, the result will be the empty array.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:trunk([ 5, 6, 7, 8 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[ 5, 6, 7 ]</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">array:trunk([ 5 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">[]</code></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="additional-array-operations" diff="add" at="2023-02-20"><head>Other Operations on Arrays</head><p><emph>This section is non-normative.</emph></p><p>Arrays may be compared using the <function>fn:deep-equal</function> function.</p><p>The XPath language provides explicit syntax for certain operations on arrays.
               These constructs can all be specified in terms of function primitives:</p><ulist><item><p>The empty array can be constructed using either of the expressions
              <code nobreak="false">[]</code> or <code nobreak="false">array{}</code>. The effect is the same as the data model primitive
              <code nobreak="false">dm:empty-array(())</code> (see <xspecref spec="XP40" ref="id-array-constructors"/>). 
                 Using user-visible functions it can be achieved
              by calling <code nobreak="false">array:build(())</code> or <code nobreak="false">array:of-members(())</code>.</p></item><item><p>The expression <code nobreak="false">array { $sequence }</code> constructs an array whose members
                 are the items in <code nobreak="false">$sequence</code>. Every member of this array will
                 be a singleton item. The effect is the same as
                 <code nobreak="false">array:build($sequence)</code>.</p></item><item><p>The expression <code nobreak="false">[<var>E1</var>, <var>E2</var>, <var>E3</var>, ..., <var>E/n</var>]</code> constructs an array in which
                 <code nobreak="false">E1</code> is the first member, <code nobreak="false">E2</code> is the second member,
                 and so on. The result is equivalent to the expression
                 <code nobreak="false">[] =&gt; array:append(<var>E1</var>) =&gt; array:append(<var>E2</var>) =&gt; ... =&gt; array:append(<var>E/n</var>))). </code></p></item><item><p>The lookup expression <code nobreak="false">$array?*</code> returns the
                 <xtermref spec="XP40" ref="dt-sequence-concatenation">sequence concatenation</xtermref>
                 of the members of the array. It is equivalent to calling 
                 <code nobreak="false">array:fold-left($array, (), fn($result, $next){ $result, $next })</code>.</p></item><item><p>The lookup expression <code nobreak="false">$array?$N</code>, where <code nobreak="false">$N</code>
                 is an integer within the bounds of the array, is equivalent to 
                 <code nobreak="false">array:get($array, $N)</code>.</p></item><item><p>Similarly, applying the array as a function, <code nobreak="false">$array($N)</code>,
                 is also equivalent to <code nobreak="false">array:get($array, [$N])</code></p></item><item><p>The expression <code nobreak="false">for member $m in $array return <var>EXPR</var></code>
               is equivalent to <code nobreak="false">array:for-each($array, fn($m){ <var>EXPR</var> })</code>
                  (see <xspecref spec="XQ40" ref="id-xquery-for-clause"/> and 
                  <xspecref spec="XP40" ref="id-for-expressions"/>).</p></item><item><p>Arrays can be filtered using the construct <code nobreak="false">$array?[<var>predicate</var>]</code>
               (see <xspecref spec="XP40" ref="id-filter-maps-and-arrays"/>).</p></item></ulist></div2></div1><div1 id="processing-jnodes"><head>Processing JNodes</head><changes><change issue="2025" PR="2031" date="2025-06-11">
              Introduced the concept of JNodes.
            </change></changes><p>A <xtermref spec="DM40" ref="dt-JNode"/> is a wrapper around a map or array, or around a value
         that appears within the content of a map or array. JNodes are described 
         at <xspecref spec="DM40" ref="id-JNodes"/>. Wrapping a map or array in a JNode enables
         the use of path expressions such as <code nobreak="false">$jnode/descendant::title</code>, as described
         at <xspecref spec="XP40" ref="id-path-expressions"/>.</p><p>In addition to the functions defined in this section, functions that operate on JNodes include:</p><slist><sitem><function>fn:distinct-ordered-nodes</function></sitem><sitem><function>fn:generate-id</function></sitem><sitem><function>fn:has-children</function></sitem><sitem><function>fn:innermost</function></sitem><sitem><function>fn:outermost</function></sitem><sitem><function>fn:path</function></sitem><sitem><function>fn:root</function></sitem><sitem><function>fn:siblings</function></sitem><sitem><function>fn:transitive-closure</function></sitem></slist><div2 id="functions-on-jnodes"><head>Functions on JNodes</head><div3 id="func-jtree"><head>fn:jtree</head><changes><change issue="2025" PR="2031" date="2025-06-12">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Delivers a root <xtermref spec="DM40" ref="dt-JNode"/> wrapping 
            a map or array, enabling the use of lookup expression
            to navigate a <xtermref spec="DM40" ref="dt-JTree"/> rooted at that map or array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="jtree" return-type="jnode((), (map(*)|array(*)))" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="(map(*)|array(*))"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function creates a <xtermref spec="DM40" ref="dt-JNode"/>
            that wraps the supplied map or array. Specifically, it creates a root JNode
            whose <term>·jvalue·</term> property is <code nobreak="false">$input</code>, and whose
            <term>·jparent·</term>, <term>·jposition·</term>, and <term>·jkey·</term> 
            properties are absent.</p><p>This has the effect that lookup expressions starting from this JNode retain
            information for subsequent navigation.</p><p>A JNode has unique identity. If two maps or arrays <var>M1</var> and
            <var>M2</var> have the same function identity, as determined by the
            <function>function-identity</function> function, then
            <code nobreak="false">jtree(<var>M1</var>) is jtree(<var>M2</var>)</code> <rfc2119>must</rfc2119>
            return true: that is, the same JNode must be
            delivered for both.</p></def></gitem><gitem><label>Notes</label><def><note><p>It is to some extent <termref def="implementation-defined"/>
         whether two maps or arrays have the same function identity. Processors
         <rfc2119>should</rfc2119> ensure as a minimum that when 
            a variable <code nobreak="false">$m</code> is bound to a map or array,
         calling <code nobreak="false">jtree($m)</code> more than once (with the same variable reference)
         will deliver the same JNode each time.</p><p>The effect of the coercion rules is technically that if an existing JNode is supplied as <code nobreak="false">$input</code>,
         the wrapped value will be extracted, and then rewrapped as a JNode: in practice,
         this can be short-circuited by returning the supplied JNode unchanged.</p><p>Although <function>fn:jnode</function> is available as a function for user applications
         to call explicitly, it is also invoked implicitly by some expressions, notably when
         a path expression is written in a form such as <code nobreak="false">$map/child::*</code>. Specifically,
         if the left-hand operand of the <code nobreak="false">/</code> operator is a map or array, 
            then the supplied map or array is implicitly wrapped in a JNode. </p><p>The effect of applying <function>fn:jnode</function> to a map or array is that subsequent retrieval operations
         within the wrapped map or array return results that retain useful information about
         where the results were found. For example, consider an expression such as <code nobreak="false">json-doc($source)//name</code>.
      
         This expression returns a set of JNodes representing all entries in the JTree having the key <code nobreak="false">"name"</code>; 
         each of these JNodes contains not only the value of the relevant <code nobreak="false">"name"</code> entry,
            but also the key (which in this simple example is always <code nobreak="false">"name"</code>
            and the containing map. This means, for example, if <code nobreak="false">$result</code>
            is the result of the expression <code nobreak="false">json-doc($source)//name</code>, then:</p><ulist><item><p><code nobreak="false">$result/../ssn</code> locates the map that contained each
               <code nobreak="false">name</code>, and returns the value of the <code nobreak="false">ssn</code> entry in that map.</p></item><item><p><code nobreak="false">$result/ancestor::course</code> returns any
            <code nobreak="false">course</code> entries in containing maps.</p></item><item><p><code nobreak="false">$result/ancestor::* =&gt; jkey() </code> returns a sequence of map keys and array index
            values representing the location of the found entries within the JSON structure.</p></item></ulist><p>An alternative way of wrapping a map or array, rather than calling <code nobreak="false">jtree($X)</code>,
         is to use the path expression <code nobreak="false">$X/.</code>.</p><p>There are two situations where a map or array is implicitly wrapped in a JNode:</p><ulist><item><p>When the value of the left-hand operand of the <code nobreak="false">/</code> operator
            includes a map or array;</p></item><item><p>When the context value for evaluation of an <code nobreak="false">AxisStep</code>
            includes a map or array.</p></item></ulist></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">jtree([ "a", "b", "c" ])/*[1]/../*[last()] =&gt; string()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"c"</code></p><p><emph>(The call on <code nobreak="false">fn:tree</code> would happen automatically).</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">jtree([ "a", "b", "c", "d" ])/* =!&gt; jkey()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">1, 2, 3, 4</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $data := {
  "fr": { "capital": "Paris", "languages": [ "French" ] }, 
  "de": { "capital": "Berlin", "languages": [ "German" ] }
}
return jtree($data)//languages[. = 'German']/../capital =!&gt; string()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Berlin"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-jkey"><head>fn:jkey</head><changes><change issue="2025" PR="2031" date="2025-06-12">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the <term>·jkey·</term> property of a JNode.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="jkey" return-type="xs:anyAtomicType?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="jnode()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$input</code> is the empty sequence, the function returns the empty sequence.</p><p>If <code nobreak="false">$input</code> is a root JNode (one in which the <term>·jkey·</term> property is
            absent), the function returns the empty sequence.</p><p>Otherwise, the function returns the <term>·jkey·</term> property of <code nobreak="false">$input</code>.
         In the case where the parent JNode wraps a map, this will be the key of the relevant entry
         within that map; in the case where the parent JNode wraps an array, it will be the 1-based
         index of the relevant member of the array.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/>.</p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">jnode()?</code>, 
                  type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $array := [ 1, 3, 4.5, 7, "eight", 10 ]
return $array/jnode(*, xs:integer) =!&gt; jkey()
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 2, 4, 6</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $map := { 'Mo': 'Monday', 'Tu': 'Tuesday', 'We': 'Wednesday' }
return $map/child::get(("Mo", "We", "Fr", "Su")) =!&gt; jkey()
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Mo", "We"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $array := [ [ 4, 18 ], [ 30, 4, 22 ] ]
return $array/descendant::*[. &gt; 25]/ancestor-or-self::* =!&gt; jkey()
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">2, 1</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-jvalue"><head>fn:jvalue</head><changes><change issue="2025" PR="2031" date="2025-06-12">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the <term>·jvalue·</term> property of a JNode.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="jvalue" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="jnode()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$input</code> is the empty sequence, the function returns the empty sequence.</p><p>Otherwise, the function returns the <term>·jvalue·</term> property of <code nobreak="false">$input</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/>.</p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">jnode()?</code>, 
                  type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>In many cases it is unnecessary to make an explicit call on <code nobreak="false">jvalue</code>, because
         the coercion rules will take care of this automatically. For example, in an expression
         such as <code nobreak="false">$X / descendant::name [matches(., '^J')]</code>, the call on
         <function>matches</function> is supplied with a JNode as its first argument; atomization
         ensures that the actual value being passed to the first argument of <function>matches</function>
            is the atomized value of the 
          <term>·jvalue·</term> property.</p><p>Other examples where the <term>·jvalue·</term> of a JNode is extracted automatically
         include:</p><ulist><item><p>Any context where the required type is an atomic value, for example
            arithmetic operations, value comparisons and general comparisons, and calls
            on functions that expect an atomic value.</p></item><item><p>Any context where the required type is a map or array, for example
            the first argument of functions such as <function>map:size</function>
               or <code nobreak="false">array:size</code>, a free-standing expression within a map
               constructor such as <code nobreak="false">map{ $jnode }</code>, the constructs
            <code nobreak="false">for member</code> and <code nobreak="false">for key/value</code>, the left-hand
            operand of the lookup operator <code nobreak="false">?</code> (or the context value
            in the case of a unary lookup operator), and the operand of a map/array
            filter expression <code nobreak="false">$jnode?[predicate]</code>.</p></item></ulist><p>Notable places where the <term>·jvalue·</term> is <emph>not</emph>
         automatically extracted include:</p><ulist><item><p>When computing the effective boolean
         value. As with XNodes, writing <code nobreak="false">if ($array/child::*[1]) ...</code> tests for the existence
         of a child, it does not test its value. To test its value, write
         <code nobreak="false">if (jvalue($array/child::*[1])) ...</code>,
         or equivalently <code nobreak="false">if (xs:boolean($array/child::*[1])) ...</code>.</p></item><item><p>When calling functions that accept arbitrary sequences, such as
            <function>count</function> or <function>deep-equal</function>.</p></item></ulist><p>It is possible (though probably unwise) to construct a JNode whose <term>·jvalue·</term>
         property itself contains another JNode. For example, the expression 
         <code nobreak="false">jtree([jtree([]), jtree([])])</code> creates a JNode whose <term>·jvalue·</term>
         is an array of JNodes, and applying the <code nobreak="false">child</code> axis to this JNode will
         return a sequence of two JNodes that themselves have further JNodes as their content.
         The <function>jvalue</function> returns these contained JNodes, it does not
         recursively extract their content.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $array := [ 1, 3, 4.5, 7, "eight", 10 ]
return $array/jnode(*, xs:integer) =!&gt; jvalue()
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1, 3, 7, 10</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $map := { 'Mo': 'Monday', 'Tu': 'Tuesday', 'We': 'Wednesday' }
return $map/child::get(("Mo", "We", "Fr", "Su")) =!&gt; jvalue()
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">"Monday", "Wednesday"</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $array := [ [ 4, 18 ], [ 30, 4, 22 ] ], [ 30, 4, 22 ]
return $array/descendant::*[. &gt; 25][1]/ancestor-or-self::* =!&gt; jvalue()</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ [ 4, 18 ], [ 30, 4, 22 ] ], [ 30, 4, 22 ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-jposition"><head>fn:jposition</head><changes><change issue="2025" PR="2031" date="2025-06-12">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns the <term>·jposition·</term> property of a JNode.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="jposition" return-type="xs:integer?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="jnode()?" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$input</code> is the empty sequence, the function returns the empty sequence.</p><p>If <code nobreak="false">$input</code> is a root JNode (one in which the <term>·jposition·</term> property is
            absent), the function returns the empty sequence.</p><p>Otherwise, the function returns the <term>·jposition·</term> property of <code nobreak="false">$input</code>.
            The value of this property will be 1 (one) except in cases where 
            the value of an entry in a map, or a member in an array, is a sequence that contains
            multiple items including maps and/or arrays; in such cases
            the position will be the 1-based position of the relevant map or array.</p></def></gitem><gitem><label>Error Conditions</label><def><p>The following errors may be raised when <code nobreak="false">$node</code> is omitted:</p><ulist><item><p>If the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>,
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/>.</p></item><item><p>If the context value is not an instance of the sequence type <code nobreak="false">jnode()?</code>, 
                  type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p></item></ulist></def></gitem><gitem><label>Notes</label><def><note><p>This function is relevant only when there are maps whose entries are multi-item
            sequences that include maps and arrays, or arrays whose members include
            such multi-item sequences.
         Such structures are uncommon, and never arise from parsing of JSON source text.
         It is generally best to avoid such structures by using arrays rather than sequences
         within array and map content; apart from other considerations, this allows the
         data to be serialized in JSON format.</p><p>If an entry within a map, or a member of an array, contains a sequence of items
         that mixes arrays and maps with other content (for example the array
          <code nobreak="false">[1, 2, ([1,2], [3,4], 5))</code>, then a lookup using the
            child axis will only construct JNodes in respect of those items that are
            non-empty maps or arrays. This may leave gaps in the position numbering sequence,
            as illustrated in the examples below.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $input := {
   "a": [ 10, 20, 30 ], 
   "b": ([ 40, 50, 60 ], [], 0, [ 70, 80, (90, 100) ])
}
return $input/b/* ! { "position": jposition(), "index": jkey(), "value": jvalue() }
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
{ "position": 1, "index": 1, "value": 40 },
{ "position": 1, "index": 2, "value": 50 },
{ "position": 1, "index": 3, "value": 60 },
{ "position": 4, "index": 1, "value": 70 },
{ "position": 4, "index": 2, "value": 80 },
{ "position": 4, "index": 3, "value": (90, 100) }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $input := {
   "a": { "x": 10, "y": 20, "z": 30 }, 
   "b": ({ "x": 40, "y": 50, "z": 60 }, {}, { "x": 70, "y": 80, "z": (90, 100) })
}
return $input/b/* ! { "position": jposition(), "key": jkey(), "value": jvalue() }
               </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
{ "position": 1, "key": "x", "value": 40 },
{ "position": 1, "key": "y", "value": 50 },
{ "position": 1, "key": "z", "value": 60 },
{ "position": 3, "key": "x", "value": 70 },
{ "position": 3, "key": "y", "value": 80 },
{ "position": 3, "key": "z", "value": (90, 100) }</eg></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="parsing-and-serializing"><head>External resources and data formats</head><p>These functions in this section access resources external to a query or stylesheet,
            and convert between external file formats and their XPath and XQuery data model 
            representation.</p><div2 id="fns-on-docs"><head>Accessing external information</head><p>The functions in this section provide access to resources (such as files) in the external environment.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:doc</code></td><td rowspan="1" colspan="1">Retrieves a document using a URI supplied as an <code nobreak="false">xs:string</code>, and returns the
            corresponding document node.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:doc-available</code></td><td rowspan="1" colspan="1">The function returns <code nobreak="false">true</code> if and only if the function call <code nobreak="false">fn:doc($source, $options)</code>
            would return a document node.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:collection</code></td><td rowspan="1" colspan="1">Returns a sequence of items identified by a
            collection URI; or a default collection if no URI is supplied.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:uri-collection</code></td><td rowspan="1" colspan="1">Returns a sequence of <code nobreak="false">xs:anyURI</code> values representing the URIs in a URI
            collection.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:unparsed-text</code></td><td rowspan="1" colspan="1">The <function>fn:unparsed-text</function> function reads an external resource (for example, a
            file) and returns a string representation of the resource.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:unparsed-text-lines</code></td><td rowspan="1" colspan="1">The <function>fn:unparsed-text-lines</function> function reads an external resource (for
            example, a file) and returns its contents as a sequence of strings, one for each line of
            text in the string representation of the resource.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:unparsed-text-available</code></td><td rowspan="1" colspan="1">Allows an application to determine
            whether a call on <function>fn:unparsed-text</function> with particular arguments 
            would succeed.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:unparsed-binary</code></td><td rowspan="1" colspan="1">The <code nobreak="false">fn:unparsed-binary</code> function reads an external resource (for example, a
            file) and returns its contents in binary.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:environment-variable</code></td><td rowspan="1" colspan="1">Returns the value of a system environment variable, if it exists.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:available-environment-variables</code></td><td rowspan="1" colspan="1">Returns a list of environment variable names that are suitable for passing to
               <function>fn:environment-variable</function>, as a (possibly empty) sequence of strings.</td></tr></tbody></table><div3 id="func-doc"><head>fn:doc</head><changes><change issue="898" PR="905" date="2024-01-09">The rule that multiple calls on <function>fn:doc</function>
            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).</change><change issue="1021" PR="1910" date="2025-04-06">An <code nobreak="false">$options</code> parameter is added. Note that the rules for the <code nobreak="false">$options</code> 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.</change></changes><glist><gitem><label>Summary</label><def><p>Retrieves a document using a URI supplied as an <code nobreak="false">xs:string</code>, and returns the
            corresponding document node.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="doc" return-type="document-node()?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		available documents, and executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$source</code> is the empty sequence, the result is the empty sequence.</p><p>If <code nobreak="false">$source</code> is a relative URI reference, it is resolved relative to the value

            of the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> property 
            from the dynamic context of the caller. The resulting absolute URI is
            promoted to an <code nobreak="false">xs:string</code>.</p><p>The way in which an absolute URI is dereferenced to obtain an external resource is 
            described in <xspecref spec="XP40" ref="id-security-resources"/>.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note><p>The URI may include a fragment identifier.</p><p>The <code nobreak="false">$options</code> argument defines the detailed behavior of the function.
            The <termref def="option-parameter-conventions"/> apply. The options available
            are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="trusted" type="xs:boolean" occur="opt"/><arg name="dtd-validation" type="xs:boolean" occur="opt"/><arg name="stable" type="xs:boolean" occur="opt"/><arg name="strip-space" type="xs:boolean?" occur="opt"/><arg name="xinclude" type="xs:boolean" occur="opt"/><arg name="xsd-validation" type="xs:string" occur="opt"/><arg name="use-xsi-schema-location" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="3" colspan="1"><p><code nobreak="false">trusted?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Indicates whether processing the document may cause other
                  external resources to be fetched (including, for example, external entities, an external DTD,
                  or documents referenced using <code nobreak="false">xsi:schemaLocation</code> or
                  XInclude elements).<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false()</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The document may include references to other external
                     resources.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">The document must not include references to other
                     external resources unless access to these resources has been explicitly
                     enabled.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">dtd-validation?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether DTD validation takes place.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The input is parsed using a validating XML parser.
                  The input must contain a <code nobreak="false">DOCTYPE</code> declaration to identify
                  the DTD to be used for validation. The DTD may be internal or external.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">DTD validation does not take place. However, if a
                     <code nobreak="false">DOCTYPE</code> declaration is present, then it is read, for example
                     to perform entity expansion.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">stable?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether two calls on the <function>doc</function> function,
               with the same URI, the same options, and the same context, are guaranteed to return
               the same document node. The default value is <code nobreak="false">true</code>, but this may be overridden
               by implementation-defined configuration options.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">Given the same explicit and implicit arguments, multiple
                     calls return the same document node: that is, the function is <termref def="dt-deterministic"/>.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">Multiple calls with the same explicit and implicit arguments
                     may return the same document node or different document nodes at the discretion of
                     the implementation.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">strip-space?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether whitespace-only text nodes are removed
                  from the resulting document. The default is defined by the host language
                  or by the implementation. (Note: in XSLT, the <code nobreak="false">xsl:strip-space</code>
                  and <code nobreak="false">xsl:preserve-space</code> declarations provide detailed control
                  based on the parent element name.)<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean?</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">All whitespace-only text nodes are stripped,
                  unless either (a) they are within the scope of the attribute <code nobreak="false">xml:space="preserve"</code>,
                  or (b) XSD validation identifies that the parent element has a simple type or a complex
                  type with simple content.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">All 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.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">xinclude?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether any <code nobreak="false">xi:include</code> elements in the input
                  are to be processed using an XInclude processor.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">Any <code nobreak="false">xi:include</code> elements are expanded. If there are
                     <code nobreak="false">xi:include</code> elements and no XInclude processor is available then 
                     a dynamic error is raised.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">Any <code nobreak="false">xi:include</code> elements are handled as
                     ordinary elements without expansion.
                  </td></tr><tr><td rowspan="5" colspan="1"><p><code nobreak="false">xsd-validation?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether XSD validation takes place, using the
                  schema definitions present in the static context. The effect of requesting
               validation is the same as invoking the <function>doc</function> function without
               validation, and then applying an XQuery <code nobreak="false">validate</code> expression to the result,
               with corresponding options.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">"skip"</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">strict</code></td><td rowspan="1" colspan="1">Strict XSD validation takes place</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">lax</code></td><td rowspan="1" colspan="1">Lax XSD validation takes place</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">skip</code></td><td rowspan="1" colspan="1">No XSD validation takes place</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">type Q{uri}local</code></td><td rowspan="1" colspan="1">XSD validation takes place against the
                  schema-defined type, present in the static context, that has the given URI
                  and local name.</td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">use-xsi-schema-location?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">When XSD validation takes place, determines whether
                  schema components referenced using <code nobreak="false">xsi:schemaLocation</code> or <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
                  attributes within the source document are to be used. The option is ignored
                  if XSD validation does not take place.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">XSD validation uses the schema components referenced 
                  using <code nobreak="false">xsi:schemaLocation</code> or <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
                  attributes in addition to the schema components present in the static context;
                  these components must be compatible as described in <xspecref spec="DM40" ref="schema-consistency"/>.</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">Any <code nobreak="false">xsi:schemaLocation</code> and <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
                  attributes in the document are ignored.</td></tr></tbody></table><p>By default, this function is <termref def="dt-deterministic">deterministic</termref>. Two
            calls on this function return the same document node if the same URI Reference (after
            resolution to an absolute URI Reference) is supplied to both calls. Thus, the following
            expression (if it does not raise an error) will always return <code nobreak="false">true</code>:</p><eg xml:space="preserve">doc("foo.xml") is doc("foo.xml")</eg><note diff="add" at="issue898"><p>This equivalence applies only because the two calls on
            the <function>fn:doc</function> function have the same options and the same 
            static and dynamic context, to the extent this is relevant. 
            If two calls on <function>fn:doc</function>
           have different dynamic contexts, then the mapping from URIs to document
         nodes in the two contexts may differ, which means that different document nodes may be returned
         for the same URI.
         This can happen, for example, if the two calls appear in different XSLT packages with different
         validation options or whitespace-stripping options; one call might produce a schema-validated
         document, the other an untyped document.</p></note><p>The requirement to deliver a deterministic result has performance implications, 
            and for this reason implementations may provide a user option to evaluate
            the function without a guarantee of determinism. The manner in which any such option is
            provided is <termref def="implementation-defined"/>. If the user has not selected such an option, a call
            of the function must either return a deterministic result or must raise a dynamic error
               <errorref class="DC" code="0003"/>.</p><note><p>If the <code nobreak="false">$source</code> URI is obtained from a source document, it is generally appropriate to
               resolve it relative to the base URI property of the relevant node in the source
               document. This can be achieved by calling the <function>fn:resolve-uri</function> function,
               and passing the resulting absolute URI as an argument to the <function>fn:doc</function>
               function.</p></note><p>If two calls to this function supply different absolute URI References as arguments, the
            same document node may be returned if the implementation can determine that the two
            arguments refer to the same resource.</p><p> By defining the semantics of this function in terms of a string-to-document-node
            mapping in the dynamic context, the specification is acknowledging that the results of
            this function are outside the purview of the language specification itself, and depend
            entirely on the run-time environment in which the expression is evaluated. This run-time
            environment includes not only an unpredictable collection of resources (“the web”), but
            configurable machinery for locating resources and turning their contents into document
            nodes within the XPath data model. Both the set of resources that are reachable, and the
            mechanisms by which those resources are parsed and validated, are <termref def="implementation-dependent">implementation-dependent</termref>.</p><p> One possible processing model for this function is as follows. The resource identified
            by the URI Reference is retrieved. If the resource cannot be retrieved, a dynamic error
            is raised <errorref class="DC" code="0002"/>. The data resulting from the retrieval
            action is then parsed as an XML document and a tree is constructed in accordance with
            the <bibref ref="xpath-datamodel-30"/>. If the top-level media type is known and is
            <code nobreak="false">"text"</code>, the content is parsed in the same way as if the media type were text/xml;
            otherwise, it is parsed in the same way as if the media type were application/xml. If
            the contents cannot be parsed successfully, a dynamic error is raised <errorref class="DC" code="0002"/>. Otherwise, the result of the function is the document node
            at the root of the resulting tree. This tree is then optionally validated against a
            schema.</p><p>Various aspects of this processing are <termref def="implementation-defined">implementation-defined</termref>.
            Implementations may provide external configuration options that allow any aspect of the
            processing to be controlled by the user. In particular:</p><ulist><item><p>The set of URI schemes that the implementation recognizes is
                  implementation-defined. Implementations may allow the mapping of URIs to resources
                  to be configured by the user, using mechanisms such as catalogs or user-written
                  URI handlers.</p></item><item><p>The handling of non-XML media types is implementation-defined. Implementations may
                  allow instances of the data model to be constructed from non-XML resources, under
                  user control.</p></item><item><p>It is <termref def="implementation-defined">implementation-defined</termref> whether DTD validation and/or schema
                  validation is applied to the source document.</p></item><item><p>Implementations may provide user-defined error handling options that allow
                  processing to continue following an error in retrieving a resource, or in parsing
                  and validating its content. When errors have been handled in this way, the
                  function may return either the empty sequence, or a fallback document provided by
                  the error handler.</p></item><item><p>Implementations may provide user options that relax the requirement for the
                  function to return deterministic results.</p></item><item><p>The effect of a fragment identifier in the supplied URI 
                  is <termref def="implementation-defined">implementation-defined</termref>. One possible interpretation
               is to treat the fragment identifier as an ID attribute value, and to return a document
               node having the element with the selected ID value as its only child.</p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error <rfc2119>may</rfc2119> be raised <errorref class="DC" code="0005"/> if
               <code nobreak="false">$source</code> is not a valid URI <phrase>reference</phrase>.</p><p>A dynamic error is raised <errorref class="DC" code="0002"/> if a relative URI reference
         is supplied, and the base-URI property in the static context is absent.</p><p>A dynamic error is raised <errorref class="DC" code="0002"/> if the <term>available
               documents</term> provides no mapping for the absolutized URI.</p><p>A dynamic error is raised <errorref class="DC" code="0002"/> if the resource cannot be
            retrieved or cannot be parsed successfully as XML using the selected options.</p><p>A dynamic error is raised <errorref class="DC" code="0003"/> if the implementation is
            not able to guarantee that the result of the function will be deterministic, and the
            user has not indicated that an unstable result is acceptable.</p></def></gitem></glist></div3><div3 id="func-doc-available"><head>fn:doc-available</head><changes><change issue="1021" PR="1910" date="2025-04-06">An <code nobreak="false">$options</code> parameter is added. Note that the rules for the <code nobreak="false">$options</code> 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.</change></changes><glist><gitem><label>Summary</label><def><p>The function returns <code nobreak="false">true</code> if and only if the function call <code nobreak="false">fn:doc($source, $options)</code>
            would return a document node.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="doc-available" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		available documents, and executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$source</code> is the empty sequence, this function returns <code nobreak="false">false</code>.</p><p>If a call on <code nobreak="false">fn:doc($source, $options)</code> would return a document node, this function
            returns <code nobreak="false">true</code>.</p><p>In all other cases this function returns <code nobreak="false">false</code>. <phrase>This
         includes the case where <phrase>an invalid URI is supplied, and also the case where </phrase>
            a valid relative URI reference is supplied, and cannot be resolved,
         for example because the static base URI is absent.</phrase></p><p>The recognized values for <code nobreak="false">$options</code> are the same as for the <function>fn:doc</function>
         function. The <termref def="option-parameter-conventions"/> apply. Note that if the <code nobreak="false">stable</code>
         option is set to <code nobreak="false">true</code>, then a result of <code nobreak="false">true</code> from this function guarantees
         that a call on <function>fn:doc</function> with the same explicit and implicit arguments will succeed, whereas a
         result of <code nobreak="false">false</code> from this function guarantees that the corresponding call on <function>fn:doc</function>
         will fail. Conversely, if the <code nobreak="false">stable</code> option is set to <code nobreak="false">false</code>, then the result of this
         function provides no guarantees regarding the outcome of a call on <function>fn:doc</function> with 
         the same explicit and implicit arguments.</p></def></gitem><gitem><label>Error Conditions</label><def><p>Like any other function, <function>doc-available</function> fails with an error if 
         invalid arguments are supplied: for example if the first argument is not a string, or
         if unrecognized options are included in <code nobreak="false">$options</code>. However, it returns false
         rather than raising an error if the first argument is invalid as a URI.</p><p>The function also returns false (rather than raising an error) if the document is
         unavailable because of processor limitations, for example if schema validation is
         requested and the processor is not schema-aware.</p></def></gitem></glist></div3><div3 id="func-collection"><head>fn:collection</head><glist><gitem><label>Summary</label><def><p>Returns a sequence of items identified by a
            collection URI; or a default collection if no URI is supplied.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="collection" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		available collections, and executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>This function takes an <code nobreak="false">xs:string</code> as argument and returns a sequence of
            <phrase>items</phrase> obtained by interpreting <code nobreak="false">$source</code> as an <code nobreak="false">xs:anyURI</code> and
            resolving it according to the mapping specified in <term>available 
               collections</term> described in <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.</p><p>If <phrase><term>available collections</term></phrase> provides a mapping from this string to a
            sequence of items, the function returns that sequence. If <term>available 
               collections</term> maps the string to the empty sequence, then the function returns an
            empty sequence.</p><p>If <code nobreak="false">$source</code> is the empty sequence, the function returns the sequence of
            <phrase>items</phrase> in the default collection in the dynamic context. See <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>. </p><p>If <code nobreak="false">$source</code> is a relative URI reference, it is resolved relative to the value
            of the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> property 
            from the dynamic context of the caller. The resulting absolute URI is
            promoted to an <code nobreak="false">xs:string</code>.</p><p>By default, this function is <termref def="dt-deterministic">deterministic</termref>. This
            means that repeated calls on the function with the same argument will return the same
            result. However, for performance reasons, implementations may provide a user option to
            evaluate the function without a guarantee of determinism. The manner in which any such
            option is provided is <termref def="implementation-defined">implementation-defined</termref>. If the user has not
            selected such an option, a call to this function must either return a deterministic
            result or must raise a dynamic error <errorref class="DC" code="0003"/>.</p><p>There is no requirement that <phrase>any nodes in the result</phrase> should be in document order, nor is
            there a requirement that the result should contain no duplicates.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0002"/> if no URI is supplied and
            the value of the default collection is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p><p>A dynamic error is raised <errorref class="DC" code="0002"/> if a relative URI reference
            is supplied, and the base-URI property in the static context is absent.</p><p>A dynamic error is raised <errorref class="DC" code="0002"/> if <term>available node
               collections</term> provides no mapping for the absolutized URI.</p><p>A dynamic error <phrase><rfc2119>may</rfc2119> be</phrase> raised <errorref class="DC" code="0004"/> if <code nobreak="false">$source</code> is not
            a valid <code nobreak="false">xs:anyURI</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>In earlier versions of this specification, the primary use for the <function>fn:collection</function> function
         was to retrieve a collection of XML documents, perhaps held as lexical XML in operating
         system filestore, or perhaps held in an XML database. In this release the concept has
         been generalised to allow other resources to be retrieved: for example JSON documents might
         be returned as arrays or maps, non-XML text files might be returned as strings, and binary
         files might be returned as instances of <code nobreak="false">xs:base64Binary</code>.</p><p>The abstract concept of a collection might be realized in different ways by different
            implementations, and the ways in which URIs map to collections can be equally variable. 
            Specifying resources using URIs is
            useful because URIs are dynamic, can be parameterized, and do not rely on an external
            environment.</p></note></def></gitem></glist></div3><div3 id="func-uri-collection"><head>fn:uri-collection</head><glist><gitem><label>Summary</label><def><p>Returns a sequence of <code nobreak="false">xs:anyURI</code> values representing the URIs in a URI
            collection.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="uri-collection" return-type="xs:anyURI*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		available URI collections, and executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$source</code> is the empty sequence, the function returns the URIs in the
            <term>default URI collection</term> described in <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.</p><p>If <code nobreak="false">$source</code> is a relative URI reference, it is resolved relative to the value
            of the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> property 
            from the dynamic context of the caller. The resulting absolute URI is
            promoted to an <code nobreak="false">xs:string</code>.</p><p>The single-argument form of the function returns the sequence of URIs corresponding to
            the supplied URI in the <term>available URI collections</term> described in
               <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.</p><p>By default, this function is <termref def="dt-deterministic">deterministic</termref>. This
            means that repeated calls on the function with the same argument will return the same
            result. However, for performance reasons, implementations may provide a user option to
            evaluate the function without a guarantee of determinism. The manner in which any such
            option is provided is <termref def="implementation-defined">implementation-defined</termref>. If the user has not
            selected such an option, a call to this function must either return a deterministic
            result or must raise a dynamic error <errorref class="DC" code="0003"/>.</p><p>There is no requirement that the URIs returned by this function should all be distinct,
            and no assumptions can be made about the order of URIs in the sequence, unless the
            implementation defines otherwise.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0002"/> if no URI is supplied (that
            is, if the function is called with no arguments, or with a single argument that
            evaluates to the empty sequence), and the value of the default resource collection is
               <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p><p>A dynamic error is raised <errorref class="DC" code="0002"/> if a relative URI reference
            is supplied, and the base-URI property in the static context is absent.</p><p>A dynamic error is raised <errorref class="DC" code="0002"/> if <term>available resource
               collections</term> provides no mapping for the absolutized URI.</p><p>A dynamic error <phrase><rfc2119>may</rfc2119> be</phrase> raised <errorref class="DC" code="0004"/> if <code nobreak="false">$source</code> is not
            a valid <code nobreak="false">xs:anyURI</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>In some implementations, there might be a close relationship between <term>collections</term> (as retrieved
         by the <function>fn:collection</function> function), and <term>URI collections</term> (as retrieved by this function).
         For example, a collection might return XML documents, and the corresponding URI collection might return
         the URIs of those documents. However, this specification does not impose such a close relationship. For example, there
         may be collection URIs accepted by one of the two functions and not by the other; a collection might contain
         items that do not have any URI; or a URI collection might contain URIs that cannot be dereferenced to return any 
         resource.</p><p>In the case where <function>fn:uri-collection</function> returns the URIs of resources that
            could also be retrieved directly using <function>fn:collection</function>, there are several reasons why it 
            might be appropriate to use this function in preference
            to the <function>fn:collection</function> function. For example:</p><ulist><item><p>It allows different URIs for different kinds of resource to be dereferenced in
                  different ways: for
                  example, the returned URIs might be referenced using the
                     <function>fn:unparsed-text</function> function rather than the <function>fn:doc</function>
                  function.</p></item><item><p>In XSLT 3.0 it allows the documents in a collection to be processed in streaming mode using the
                     <code nobreak="false">xsl:stream</code> instruction.</p></item><item><p>It allows recovery from failures to read, parse, or validate individual documents,
                  by calling the <function>fn:doc</function> (or other dereferencing) function within the scope of try/catch.</p></item><item><p>It allows selection of which documents to read based on their URI, for example
                  they can be filtered to select those whose URIs end in <code nobreak="false">.xml</code>, or those
                  that use the <code nobreak="false">https</code> scheme.</p></item><item><p>An application might choose to limit the number of URIs processed in a single run,
                  for example it might process only the first 50 URIs in the collection; or it might
                  present the URIs to the user and allow the user to select which of them need to be
                  further processed.</p></item><item><p>It allows the URIs to be modified before they are dereferenced, for example by
                  adding or removing query parameters, or by redirecting the request to a local
                  cache or to a mirror site.</p></item></ulist><p>For some of these use cases, this assumes that the cost of calling
               <function>fn:collection</function> might be significant (for example, it might involving
            retrieving all the documents in the collection over the network and parsing them). This
            will not necessarily be true of all implementations.</p></note></def></gitem></glist></div3><div3 id="func-unparsed-text"><head>fn:unparsed-text</head><changes><change issue="1116" PR="1117" date="2024-05-21">The <code nobreak="false">$options</code> parameter has been added.</change><change issue="414" PR="546" date="2023-07-25">It is no longer automatically an error if the resource (after decoding) 
               contains a codepoint that is not valid in XML. Instead, the codepoint
            must be a <termref def="dt-permitted-character"/>. The set of permitted
            characters is <termref def="implementation-defined"/>, but it is
            <rfc2119>recommended</rfc2119> that all Unicode characters should 
               be accepted.</change><change issue="2221" PR="2249" date="2025-10-21">The specification now describes in more detail how to determine the effective
               encoding value.</change><change issue="2460" PR="2510" date="2026-03-11">A fallback option is now provided to address characters that cannot be
            decoded or are not permitted.</change></changes><glist><gitem><label>Summary</label><def><p>The <function>fn:unparsed-text</function> function reads an external resource (for example, a
            file) and returns a string representation of the resource.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="unparsed-text" return-type="xs:string?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/><arg name="options" type="(xs:string | map(*))?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The <code nobreak="false">$source</code> argument <rfc2119>must</rfc2119> be a string in the form of a URI
            reference, which <rfc2119>must</rfc2119> contain no fragment identifier, and
               <rfc2119>must</rfc2119> identify a resource for which a string representation is
            available.</p><p>If <code nobreak="false">$source</code> is a relative URI reference, it is resolved relative to the value
            of the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> property 
            from the dynamic context of the caller. The resulting absolute URI is
            promoted to an <code nobreak="false">xs:string</code>.</p><p>The <code nobreak="false">$options</code> argument, for backwards compatibility reasons, may be supplied
         either as a map, or as a string. Supplying a value <code nobreak="false">$S</code> that is not a map
            is equivalent to supplying the map <code nobreak="false">{ "encoding": $S }</code>.
            After that substitution, the <termref def="option-parameter-conventions"/> apply.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="encoding" type="xs:string?" occur="opt"/><arg name="normalize-newlines" type="xs:boolean" occur="opt"/><arg name="fallback" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">encoding?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">Defines the encoding of the resource, as described below.
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">normalize-newlines?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether CR and CRLF character sequences
                  are treated as equivalent to NL characters.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">No normalization of line endings takes place.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The character <char>U+000D</char>
                     and the character pair (<char>U+000D</char>, <char>U+000A</char>) are converted to the
                     single character <char>U+000A</char>.
                  </td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">fallback?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">
                  If <code nobreak="false">$fallback</code> is true, any character that 
                  cannot be decoded or that is not a <termref def="dt-permitted-character"/>
                  is replaced by the Unicode replacement character
                  (<char>U+FFFD</char>).
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr></tbody></table><p>The way in which an absolute URI is dereferenced to obtain an external resource is 
            described in <xspecref spec="XP40" ref="id-security-resources"/>.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note><p>If the <code nobreak="false">$source</code> argument is the empty sequence, the function
            returns the empty sequence.</p><p>The <code nobreak="false">encoding</code> option, if non-empty, is the name of an encoding.
            The values for this option follow the same rules as for the <code nobreak="false">encoding</code> attribute
            in an XML declaration. The values which an implementation is <rfc2119>required</rfc2119>
            to recognize are <code nobreak="false">UTF-8</code>, <code nobreak="false">UTF-16</code>, <code nobreak="false">UTF-16LE</code>,
            and <code nobreak="false">UTF-16BE</code> (in any upper/lower case combination).</p><p>The effective encoding is chosen as follows:</p><olist><item><p>external encoding information if available; otherwise</p></item><item><p>the encoding recognized as specified in <bibref ref="xml"/> if the media type
                  of the resource is <code nobreak="false">text/xml</code> or <code nobreak="false">application/xml</code>
                  (see <bibref ref="rfc2376"/>), or if it matches the conventions
                  <code nobreak="false">text/*+xml</code> or <code nobreak="false">application/*+xml</code>
                  (see <bibref ref="rfc7303"/> and/or its successors); otherwise</p></item><item><p>the value of the <code nobreak="false">encoding</code> option if present; otherwise</p></item><item><p>the encoding inferred from the initial octets of the resource,
               or from <termref def="implementation-defined"/> heuristics
               as defined by the rules of the <function>bin:infer-encoding</function>
               function.</p></item></olist><note><p>Encoding names are compared without regard to case.</p></note><p>If the input (as decoded using the effective encoding) starts with a byte order mark,
            then the byte order mark is not included in the result.</p><p>The result of the function is a string containing the string representation of the
            resource retrieved using the URI, decoded according to the effective encoding.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="UT" code="1170"/> if the <code nobreak="false">$source</code> argument
            contains a fragment identifier, <phrase>or if it cannot be resolved
            to an absolute URI (for example, because the base-URI property in the static context is absent), 
            </phrase>or if it cannot be used to retrieve the string
            representation of a resource. </p><p diff="chg" at="2023-06-12">A dynamic error is raised <errorref class="UT" code="1190"/> if the value of the
            <code nobreak="false">encoding</code> option is not a valid encoding name, if the
            processor does not support the specified encoding, if
            the string representation of the retrieved resource contains octets that cannot be
            decoded into Unicode <termref def="character">characters</termref> using the specified
            encoding, or if any resulting character is not a
            <termref def="dt-permitted-character">permitted character</termref>.</p><p>A dynamic error is raised <errorref class="UT" code="1200"/> if the <code nobreak="false">encoding</code> option
            is absent and the processor cannot infer the
            encoding using external information and the actual encoding is not UTF-8.</p></def></gitem><gitem><label>Notes</label><def><note><p>If it is appropriate to use a base URI other than the 
            <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> (for example,
            when resolving a relative URI reference read from a source document) then it is
            advisable to resolve the relative URI reference using the <function>fn:resolve-uri</function>
            function before passing it to the <function>fn:unparsed-text</function> function.</p><p>There is no essential relationship between the sets of URIs accepted by the two
            functions <function>fn:unparsed-text</function> and <function>fn:doc</function> (a URI accepted by one
            may or may not be accepted by the other), and if a URI is accepted by both there is no
            essential relationship between the results (different resource representations are
            permitted by the architecture of the web).</p><p>There are no constraints on the MIME type of the resource.</p><p>The fact that the resolution of URIs is defined by a mapping in the dynamic context
            means that in effect, various aspects of the behavior of this function are <termref def="implementation-defined">implementation-defined</termref>. Implementations may provide external configuration
            options that allow any aspect of the processing to be controlled by the user. In
            particular:</p><ulist><item><p>The set of URI schemes that the implementation recognizes is
                  implementation-defined. Implementations may allow the mapping of URIs to resources
                  to be configured by the user, using mechanisms such as catalogs or user-written
                  URI handlers.</p></item><item><p>The handling of media types is implementation-defined.</p></item><item><p>Implementations may provide user options that relax the requirement for the function
               to return deterministic results.</p></item><item><p>Implementations may provide user-defined error handling options that allow
                  processing to continue following an error in retrieving a resource, or in reading
                  its content. When errors have been handled in this way, the function may return a
                  fallback document provided by the error handler.</p></item></ulist><p>The rules for determining the encoding are chosen for consistency with <bibref ref="xinclude"/>. Files with an XML media type are treated specially because there
            are use cases for this function where the retrieved text is to be included as unparsed
            XML within a CDATA section of a containing document, and because processors are likely
            to be able to reuse the code that performs encoding detection for XML external
            entities.</p><p>If the text file contains characters such as <code nobreak="false">&lt;</code> and <code nobreak="false">&amp;</code>,
            these will typically be output as <code nobreak="false">&amp;lt;</code> and <code nobreak="false">&amp;amp;</code> if
            the string is serialized as XML or HTML. If these characters actually represent markup
            (for example, if the text file contains HTML), then an XSLT stylesheet can attempt to
            write them as markup to the output file using the <code nobreak="false">disable-output-escaping</code>
            attribute of the <code nobreak="false">xsl:value-of</code> instruction. Note, however, that XSLT
            implementations are not required to support this feature.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>This XSLT example attempts to read a file containing “boilerplate” HTML and copy it
               directly to the serialized output file:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">&lt;xsl:output method="html"/&gt;

&lt;xsl:template match="/"&gt;
  &lt;xsl:value-of select="unparsed-text('header.html', 'iso-8859-1')"
                disable-output-escaping="yes"/&gt;
  &lt;xsl:apply-templates/&gt;
  &lt;xsl:value-of select="unparsed-text('footer.html', 'iso-8859-1')"
                disable-output-escaping="yes"/&gt;
&lt;/xsl:template&gt;
</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-unparsed-text-lines"><head>fn:unparsed-text-lines</head><changes><change issue="1116 1278" PR="1117 1279" date="2024-05-21">The <code nobreak="false">$options</code> parameter has been added.</change><change issue="2460" PR="2510" date="2026-03-11">A fallback option is now provided to address characters that cannot be
            decoded or are not permitted.</change></changes><glist><gitem><label>Summary</label><def><p>The <function>fn:unparsed-text-lines</function> function reads an external resource (for
            example, a file) and returns its contents as a sequence of strings, one for each line of
            text in the string representation of the resource.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="unparsed-text-lines" return-type="xs:string*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/><arg name="options" type="(xs:string | map(*))?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The <code nobreak="false">unparsed-text-lines</code> function reads an external resource (for example, a
            file) and returns its string representation as a sequence of strings, separated at
            newline boundaries.</p><p>The <code nobreak="false">$options</code> argument, for backwards compatibility reasons, may be supplied
         either as a map, or as a string. Supplying a value <code nobreak="false">$S</code> that is not a map
            is equivalent to supplying the map <code nobreak="false">{ "encoding": $S }</code>.
            After that substitution, the <termref def="option-parameter-conventions"/> apply.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="encoding" type="xs:string?" occur="opt"/><arg name="fallback" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">encoding?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Defines the encoding of the resource, following the rules of <function>fn:unparsed-text</function>.
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">fallback?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
                  If <code nobreak="false">$fallback</code> is true, any character that 
                  cannot be decoded or that is not a <termref def="dt-permitted-character"/>
                  is replaced by the Unicode replacement character
                  (<char>U+FFFD</char>).
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr></tbody></table><p>The result of the function is the same as the result of the expression:</p><eg xml:space="preserve">let $text := unparsed-text($source, map:put($options, 'normalize-newlines', true()))
let $lines := tokenize($text, '\n')
return $lines[not(position() = last() and . = '')]
         </eg><p>The result is thus a sequence of strings containing the text of the resource retrieved
            using the URI, each string representing one line of text. Lines may be delimited by
            any of the character sequences <char>U+000A</char>, <char>U+000D</char>, or <char>U+000D</char>
            followed by <char>U+000A</char>.
            Line ending characters are not
            included in the returned strings. If there are two adjacent newline sequences, a
            zero-length string will be returned to represent the empty line; but if the external
            resource ends with a newline sequence, the result will be as if this final
            line ending were not present.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note></def></gitem><gitem><label>Error Conditions</label><def><p>Error conditions are the same as for the <function>fn:unparsed-text</function> function.</p></def></gitem><gitem><label>Notes</label><def><note><p>See the notes for <function>fn:unparsed-text</function>.</p></note></def></gitem></glist></div3><div3 id="func-unparsed-text-available"><head>fn:unparsed-text-available</head><changes><change issue="1116" PR="1117" date="2024-05-21">The <code nobreak="false">$options</code> parameter has been added.</change></changes><glist><gitem><label>Summary</label><def><p>Allows an application to determine
            whether a call on <function>fn:unparsed-text</function> with particular arguments 
            would succeed.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="unparsed-text-available" return-type="xs:boolean" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/><arg name="options" type="(xs:string | map(*))?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The <function>fn:unparsed-text-available</function> function determines whether a call
            on the <function>fn:unparsed-text</function> function with identical arguments would
            return a string.</p><p>If the first argument is the empty sequence, the function returns <code nobreak="false">false</code>. </p><p>In other cases, the function returns <code nobreak="false">true</code> if a call on
               <function>fn:unparsed-text</function> or <function>fn:unparsed-text-lines</function>
            with the same arguments would succeed, and
            <code nobreak="false">false</code> if a call on <function>fn:unparsed-text</function> 
            or <function>fn:unparsed-text-lines</function> with the same arguments would
            fail with a non-recoverable dynamic error.</p><p>The functions <function>fn:unparsed-text</function> and
               <function>fn:unparsed-text-available</function> have the same requirement for
               <termref def="dt-deterministic">determinism</termref> as the functions
               <function>fn:doc</function> and <function>fn:doc-available</function>. This means that unless the
            user has explicitly stated a requirement for a reduced level of determinism, either of
            these functions if called twice with the same arguments during the course of a
            transformation <rfc2119>must</rfc2119> return the same results each time; moreover, the
            results of a call on <function>fn:unparsed-text-available</function>
            <rfc2119>must</rfc2119> be consistent with the results of a subsequent call on
               <code nobreak="false">unparsed-text</code> with the same arguments.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note></def></gitem><gitem><label>Notes</label><def><note><p>This function was introduced before XQuery and XSLT allowed errors to be caught;
            with current versions of these host languages, catching an error from
            <function>fn:unparsed-text</function> may provide a better alternative.</p><p>The specification requires that the <function>fn:unparsed-text-available</function> function should
            actually attempt to read the resource identified by the URI, and check that it is
            correctly encoded and contains no characters that are invalid in XML. Implementations
            may avoid the cost of repeating these checks for example by caching the validated
            contents of the resource, to anticipate a subsequent call on the
               <function>fn:unparsed-text</function> or <function>fn:unparsed-text-lines</function>
            function. Alternatively, implementations may be able to rewrite an expression such as
               <code nobreak="false">if (unparsed-text-available(A)) then unparsed-text(A) else ...</code> to
            generate a single call internally.</p><p>Since the function <function>fn:unparsed-text-lines</function> succeeds or fails under
            exactly the same circumstances as <function>fn:unparsed-text</function>, the
               <function>fn:unparsed-text-available</function> function may equally be used to test
            whether a call on <function>fn:unparsed-text-lines</function> would succeed.</p></note></def></gitem></glist></div3><div3 id="func-unparsed-binary"><head>fn:unparsed-binary</head><changes><change issue="557" PR="1587" date="2024-11-18">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>The <code nobreak="false">fn:unparsed-binary</code> function reads an external resource (for example, a
            file) and returns its contents in binary.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="unparsed-binary" return-type="xs:base64Binary?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The <code nobreak="false">$source</code> argument <rfc2119>must</rfc2119> be a string in the form of a URI
            reference, which <rfc2119>must</rfc2119> contain no fragment identifier, and
               <rfc2119>must</rfc2119> identify a resource for which a binary representation is
            available.</p><p>If <code nobreak="false">$source</code> is a relative URI reference, it is resolved relative to the value
            of the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> property 
            from the dynamic context of the caller. The resulting absolute URI is
            promoted to an <code nobreak="false">xs:string</code>.</p><p>The mapping of URIs to the binary representation of a resource is the mapping defined in
            the <xtermref spec="XP40" ref="dt-available-binary-resources"/> component of the dynamic context.</p><p>If the <code nobreak="false">$source</code> argument is the empty sequence, the function
            returns the empty sequence.</p><p>The result of the function is an atomic item of type <code nobreak="false">xs:base64Binary</code> 
            containing the binary representation of the
            resource retrieved using the URI.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="UT" code="1170"/> if the <code nobreak="false">$source</code> argument
            contains a fragment identifier, <phrase>or if it cannot be resolved
            to an absolute URI (for example, because the base-URI property in the static context is absent), 
            </phrase>or if it cannot be used to retrieve the binary
            representation of a resource. </p></def></gitem><gitem><label>Notes</label><def><note><p>If it is appropriate to use a base URI other than the 
            <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> (for example,
            when resolving a relative URI reference read from a source document) then it is
            advisable to resolve the relative URI reference using the <code nobreak="false">fn:resolve-uri</code>
            function before passing it to the <code nobreak="false">fn:unparsed-text</code> function.</p><p>There is no essential relationship between the sets of URIs accepted by the 
            function <code nobreak="false">fn:unparsed-binary</code> and other functions such as
            <code nobreak="false">fn:doc</code> and <code nobreak="false">fn:unparsed-text</code>  (a URI accepted by one
            may or may not be accepted by the others), and if a URI is accepted by more than 
            one of these functions then there is no
            essential relationship between the results (different resource representations are
            permitted by the architecture of the web).</p><p>There are no constraints on the MIME type of the resource.</p><p>The fact that the resolution of URIs is defined by a mapping in the dynamic context
            means that in effect, various aspects of the behavior of this function are <termref def="implementation-defined">implementation-defined</termref>. Implementations may provide external configuration
            options that allow any aspect of the processing to be controlled by the user. In
            particular:</p><ulist><item><p>The set of URI schemes that the implementation recognizes is
                  implementation-defined. Implementations may allow the mapping of URIs to resources
                  to be configured by the user, using mechanisms such as catalogs or user-written
                  URI handlers.</p></item><item><p>The handling of media types is implementation-defined.</p></item><item><p>Implementations may provide user options that relax the requirement for the function
               to return deterministic results.</p></item><item><p>Implementations may provide user-defined error handling options that allow
                  processing to continue following an error in retrieving a resource, or in reading
                  its content. When errors have been handled in this way, the function may return a
                  fallback document provided by the error handler.</p></item></ulist><p>There is no function (analogous to <code nobreak="false">fn:doc-available</code> or <code nobreak="false">fn:unparsed-text-available</code>)
            to determine whether a suitable resource is available. In XQuery and XSLT, try/catch
            constructs are available to catch the error.</p><p>The choice of <code nobreak="false">xs:base64Binary</code> rather than <code nobreak="false">xs:hexBinary</code> for the
            result is arbitrary. The two types have the same value space and are interchangeable for nearly
            all purposes, the notable exception being conversion to <code nobreak="false">xs:string</code>.</p><p>A comprehensive set of functions for manipulating binary data is available in the
            EXPath binary module: see <bibref ref="expath"/>. In addition, the EXPath file module
            provides a function <code nobreak="false">file:read-binary</code> with similar functionality to
            <code nobreak="false">fn:unparsed-binary</code>, the notable differences being (a) that it takes
            a file name rather than a URI, and (b) that it is defined to be nondeterministic.
          </p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>The following XQuery, adapted from an example in the EXPath binary module <bibref ref="expath"/>,
               reads a JPEG image and determines its size in pixels:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">declare namespace bin = "http://expath.org/ns/binary";
let $content := fn:unparsed-binary("image.jpeg")
let $int16-at := bin:unpack-unsigned-integer(
                    $content, ?, 2, 'most-significant-first')
let $loc := bin:find($content, 0, bin:hex('FFC0'))
return { "width": $int16-at($loc + 5),
         "height": $int16-at($loc + 7) }</eg></td></tr><tr><td colspan="2" rowspan="1"><p>The example assumes that the functions in the EXPath binary module are available.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-environment-variable"><head>fn:environment-variable</head><glist><gitem><label>Summary</label><def><p>Returns the value of a system environment variable, if it exists.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="environment-variable" return-type="xs:string?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="name" type="xs:string"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		environment variables.
	</p></def></gitem><gitem><label>Rules</label><def><p>The set of available <xtermref spec="XP40" ref="dt-environment-variables">environment
               variables</xtermref> is a set of (name, value) pairs forming part of the dynamic
            context, in which the name is unique within the set of pairs. The name and value are
            arbitrary strings.</p><p>If the <code nobreak="false">$name</code> argument matches the name of one of these pairs, the function
            returns the corresponding value.</p><p>If there is no environment variable with a matching name, the function returns the empty
            sequence.</p><p>The collation used for matching names is <termref def="implementation-defined">implementation-defined</termref>, but
            must be the same as the collation used to ensure that the names of all environment
            variables are unique.</p><p>The function is <termref def="dt-deterministic">deterministic</termref>, which means
            that if it is called several times within the same <termref def="execution-scope">execution scope</termref>, with the same arguments, it must return the same
            result.</p></def></gitem><gitem><label>Notes</label><def><note><p>On many platforms, the term “environment variable” has a natural meaning in terms of
            facilities provided by the operating system. This interpretation of the concept does not
            exclude other interpretations, such as a mapping to a set of configuration parameters in
            a database system.</p><p>Environment variable names are usually case sensitive. Names are usually of the form
               <code nobreak="false">(letter|_) (letter|_|digit)*</code>, but this varies by platform.</p><p>On some platforms, there may sometimes be multiple environment variables with the same
            name; in this case, it is implementation-dependent as to which is returned; see for
            example <bibref ref="POSIX.1-2008"/> (Chapter 8, Environment Variables). Implementations
               <rfc2119>may</rfc2119> use prefixes or other naming conventions to disambiguate the
            names.</p><p>The requirement to ensure that the function is deterministic means in practice that the
            implementation must make a snapshot of the environment variables at some time during
            execution, and return values obtained from this snapshot, rather than using live values
            that are subject to change at any time.</p><p>Operating system environment variables may be associated with a particular process,
            while queries and stylesheets may execute across multiple processes (or multiple
            machines). In such circumstances implementations <rfc2119>may</rfc2119> choose to
            provide access to the environment variables associated with the process in which the
            query or stylesheet processing was initiated.</p><p>Security advice: <xtermref spec="XP40" ref="dt-untrusted">Untrusted</xtermref> 
            applications should not be permitted unrestricted
            access to environment variables. For example, the name of the account under which a
            query is running may be useful information to a would-be intruder. An implementation may
            therefore choose to restrict access to the environment, or may provide a facility to
            make <function>fn:environment-variable</function> always return the empty sequence.</p></note></def></gitem></glist></div3><div3 id="func-available-environment-variables"><head>fn:available-environment-variables</head><glist><gitem><label>Summary</label><def><p>Returns a list of environment variable names that are suitable for passing to
               <function>fn:environment-variable</function>, as a (possibly empty) sequence of strings.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="available-environment-variables" return-type="xs:string*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		environment variables.
	</p></def></gitem><gitem><label>Rules</label><def><p>The function returns a sequence of strings, being the names of the environment variables
            in the dynamic context in some <termref def="implementation-dependent">implementation-dependent</termref> order.</p><p>The function is <termref def="dt-deterministic">deterministic</termref>: that is, the
            set of available environment variables does not vary during evaluation.</p></def></gitem><gitem><label>Notes</label><def><note><p>The function returns a list of strings, containing no duplicates.</p><p>It is intended that the strings in this list should be suitable for passing to
               <function>fn:environment-variable</function>.</p><p>See also the note on security under the definition of the
               <function>fn:environment-variable</function> function. If access to environment variables has
            been disabled, <function>fn:available-environment-variables</function> always returns the empty
            sequence.</p></note></def></gitem></glist></div3></div2><div2 id="xml-functions"><head>Functions on XML Data</head><p>These functions convert between the lexical representation of XML and the tree representation.</p><p>(The <function>fn:serialize</function> function also handles HTML and JSON output, but is included in this section
            for editorial convenience.)</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-xml</code></td><td rowspan="1" colspan="1">This function takes as input an XML document, and returns the
            document node at the root of an XDM tree representing the parsed document.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-xml-fragment</code></td><td rowspan="1" colspan="1">This 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.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:serialize</code></td><td rowspan="1" colspan="1">This function serializes the supplied input sequence <code nobreak="false">$input</code> as described in
               <bibref ref="xslt-xquery-serialization-31"/>, returning the serialized representation
            of the sequence as a string.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:xsd-validator</code></td><td rowspan="1" colspan="1">Given an XSD schema, delivers a function item that can be invoked to validate a document, element, or attribute node
            against this schema.</td></tr></tbody></table><div3 id="func-parse-xml"><head>fn:parse-xml</head><changes><change issue="305" PR="1257" date="2024-06-11">The <code nobreak="false">$options</code> parameter has been added.</change><change issue="1287" PR="1288" date="2024-06-25">Additional error conditions have been defined.</change><change issue="1857 1860" PR="1879" date="2025-03-18">Additional options to control DTD and XInclude processing have been added.</change><change issue="748" PR="2013" date="2025-05-20">Support for binary input has been added.</change></changes><glist><gitem><label>Summary</label><def><p>This function takes as input an XML document, and returns the
            document node at the root of an XDM tree representing the parsed document.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-xml" return-type="document-node(*)?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:string | xs:hexBinary | xs:base64Binary)?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>In other cases, <code nobreak="false">$value</code> is expected to contain an XML document supplied
            either as a string or a binary value. If it is supplied as a binary value, an optional
            byte order mark or XML declaration may contain the input encoding, and the input will be
            processed like a resource retrieved by the <function>fn:doc</function> function.
            Otherwise, if the input is a string, any byte order mark as well as the encoding specified
            in an optional XML declaration <rfc2119>should</rfc2119> be ignored.</p><p>The <code nobreak="false">$options</code> argument defines the detailed behavior of the
         function. The <termref def="option-parameter-conventions"/> apply. The options available
         are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="base-uri" type="xs:anyURI" occur="opt"/><arg name="dtd-validation" type="xs:boolean" occur="opt"/><arg name="strip-space" type="xs:boolean" occur="opt"/><arg name="trusted" type="xs:boolean" occur="opt"/><arg name="xinclude" type="xs:boolean" occur="opt"/><arg name="xsd-validation" type="xs:string" occur="opt"/><arg name="use-xsi-schema-location" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">base-uri?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">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.<ulist><item><p><term>Type: </term><code nobreak="false">xs:anyURI</code></p></item><item><p><term>Default: </term><code nobreak="false">static-base-uri()</code></p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">dtd-validation?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether DTD validation takes place.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The input is parsed using a validating XML parser.
                  The input must contain a <code nobreak="false">DOCTYPE</code> declaration to identify
                  the DTD to be used for validation. The DTD may be internal or external.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">DTD validation does not take place. However, if a
                     <code nobreak="false">DOCTYPE</code> declaration is present, then it is read, for example
                     to perform entity expansion.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">strip-space?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether whitespace-only text nodes are removed
                  from the resulting document. (Note: in XSLT, the <code nobreak="false">xsl:strip-space</code>
                  and <code nobreak="false">xsl:preserve-space</code> declarations are ignored.)<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">All whitespace-only text nodes are stripped,
                  unless either (a) they are within the scope of the attribute <code nobreak="false">xml:space="preserve"</code>,
                  or (b) XSD validation identifies that the parent element has a simple type or a complex
                  type with simple content.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">All 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.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">trusted?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Indicates whether processing the supplied document may cause 
                  external resources to be fetched (including, for example, external entities, an external DTD,
                  or documents referenced using <code nobreak="false">xsi:schemaLocation</code> or
                  XInclude elements).<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false()</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The document may include references to external
                     resources.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">The document must not include references to 
                     external resources unless access to these resources has been explicitly
                     enabled.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">xinclude?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether any <code nobreak="false">xi:include</code> elements in the input
                  are to be processed using an XInclude processor.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">Any <code nobreak="false">xi:include</code> elements are expanded. If there are
                     <code nobreak="false">xi:include</code> elements and no XInclude processor is available then 
                     a dynamic error is raised.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">Any <code nobreak="false">xi:include</code> elements are handled as
                     ordinary elements without expansion.
                  </td></tr><tr><td rowspan="5" colspan="1"><p><code nobreak="false">xsd-validation?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether XSD validation takes place, using the
                  schema definitions present in the static context. The effect of requesting
               validation is the same as invoking the <function>parse-xml</function> function without
               validation, and then applying an XQuery <code nobreak="false">validate</code> expression to the result,
               with corresponding options.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">"skip"</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">strict</code></td><td rowspan="1" colspan="1">Strict XSD validation takes place</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">lax</code></td><td rowspan="1" colspan="1">Lax XSD validation takes place</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">skip</code></td><td rowspan="1" colspan="1">No XSD validation takes place</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">type Q{uri}local</code></td><td rowspan="1" colspan="1">XSD validation takes place against the
                  schema-defined type, present in the static context, that has the given URI
                  and local name.</td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">use-xsi-schema-location?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">When XSD validation takes place, determines whether
                  schema components referenced using <code nobreak="false">xsi:schemaLocation</code> or <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
                  attributes within the source document are to be used. The option is ignored
                  if XSD validation does not take place.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">XSD validation uses the schema components referenced 
                  using <code nobreak="false">xsi:schemaLocation</code> or <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
                  attributes in addition to the schema components present in the static context;
                  these components must be compatible as described in <xspecref spec="DM40" ref="schema-consistency"/>.</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">Any <code nobreak="false">xsi:schemaLocation</code> and <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
                  attributes in the document are ignored.</td></tr></tbody></table><p>Except to the extent defined by these options, the precise process used 
            to construct the XDM instance is <termref def="implementation-defined">implementation-defined</termref>. In particular, it is implementation-defined whether an XML
            1.0 or XML 1.1 parser is used.</p><p>The document URI of the returned node is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p><p>The function is <emph>not</emph>
            <termref def="dt-deterministic">deterministic</termref>: that is, if the function is called
            twice with the same arguments, it is <termref def="implementation-dependent">implementation-dependent</termref> whether the same node is returned on both
            occasions.</p><p>Options set in <code nobreak="false">$options</code> may be supplemented or modified based on 
            configuration options defined externally using <termref def="implementation-defined"/> 
            mechanisms.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0006"/> if the content of
               <code nobreak="false">$value</code> is not a well-formed and namespace-well-formed XML document.</p><p>A dynamic error is raised <errorref class="DC" code="0007"/> if DTD validation is
            carried out and the content of <code nobreak="false">$value</code> is not valid against the relevant DTD.</p><p>A dynamic error is raised <errorref class="DC" code="0008"/> if the value of the <code nobreak="false">xsd-validation</code> option is not one of the
            permitted values (for example, if the string that follows <code nobreak="false">"type"</code>
            is not a valid <code nobreak="false">EQName</code>, or if it does not identify a type that is present in the
            static context).</p><p>A dynamic error is raised <errorref class="DC" code="0009"/> if the value of the <code nobreak="false">xsd-validation</code> option is set to anything
            other than <code nobreak="false">skip</code> 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.)</p><p>A dynamic error is raised <errorref class="DC" code="0013"/> 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.</p><p>A dynamic error is raised <errorref class="DC" code="0014"/> if XSD validation is
            carried out and the content of <code nobreak="false">$value</code> is not valid against the relevant XSD schema.</p></def></gitem><gitem><label>Notes</label><def><note><p>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.</p><p>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 is
            exposed as text, the receiving query or stylesheet may pass this text to the
               <function>fn:parse-xml</function> function to create a tree representation of the nested
            document.</p><p>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.</p><p>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
               <function>fn:unparsed-text</function> function, editing the resulting string, and then
            passing it to the <function>fn:parse-xml</function> function.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">fn:parse-xml("&lt;alpha&gt;abcd&lt;/alpha&gt;")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>A newly
               created document node, having an <code nobreak="false">alpha</code> element as its only child; the
                  <code nobreak="false">alpha</code> element in turn is the parent of a text node whose string value
               is <code nobreak="false">"abcd"</code>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">fn:parse-xml("&lt;alpha&gt;&lt;beta&gt; &lt;/beta&gt;&lt;/alpha&gt;", { "strip-space": true() })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>A newly
               created document node, having an <code nobreak="false">alpha</code> element as its only child; the
                  <code nobreak="false">alpha</code> element in turn is the parent of a <code nobreak="false">beta</code>
               element whose content is empty, as a result of whitespace stripping.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-parse-xml-fragment"><head>fn:parse-xml-fragment</head><changes><change issue="305" PR="1257" date="2024-06-11">The <code nobreak="false">$options</code> parameter has been added.</change><change issue="748" PR="2013" date="2025-05-20">Support for binary input has been added.</change></changes><glist><gitem><label>Summary</label><def><p>This 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.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-xml-fragment" return-type="document-node()?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:string | xs:hexBinary | xs:base64Binary)?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>If the input is supplied as a binary value, the function detects the encoding using the
            same rules as the <function>unparsed-text</function> function, except that the special
            handling of media types such as <code nobreak="false">text/xml</code> and <code nobreak="false">application/xml</code> may be skipped.
            Otherwise, if the input is a string, any byte order mark as well as the encoding specified
            in an optional XML declaration <rfc2119>should</rfc2119> be ignored.</p><p>The input must be a namespace-well-formed external general parsed entity. More
            specifically, it must conform to the production rule <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XML" ref="NT-extParsedEnt" xlink:type="simple">extParsedEnt</xnt> in <bibref ref="xml"/>, it must contain
            no entity references other than references to predefined entities, and it must satisfy
            all the rules of <bibref ref="xml-names"/> for namespace-well-formed documents with
            the exception that the rule requiring it to be a well-formed document is replaced by the
            rule requiring it to be a well-formed external general parsed entity.</p><p>The input is parsed to form a sequence of nodes which become children of the new
            document node, in the same way as the content of any element is converted into a
            sequence of children for the resulting element node.</p><p>The <code nobreak="false">$options</code> argument defines the detailed behavior of the
         function. The <termref def="option-parameter-conventions"/> apply. The options available
         are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="base-uri" type="xs:anyURI" occur="opt"/><arg name="strip-space" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">base-uri?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">Determines the base URI. This is used 
                  as the base URI of the document node that is returned. It defaults
                  to the static base URI of the function call.<ulist><item><p><term>Type: </term><code nobreak="false">xs:anyURI</code></p></item><item><p><term>Default: </term><code nobreak="false">static-base-uri()</code></p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">strip-space?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether whitespace-only text nodes are removed
                  from the resulting document.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">All whitespace-only text nodes are stripped,
                  unless they are within the scope of the attribute <code nobreak="false">xml:space="preserve"</code>.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">All whitespace-only text nodes are preserved.
                  </td></tr></tbody></table><p>DTD validation is <emph>not</emph> invoked (an external general parsed entity cannot contain
            a <code nobreak="false">DOCTYPE</code> declaration.</p><p>Schema validation is <emph>not</emph> invoked, which means that the nodes in the
            returned document will all be untyped.</p><p>XInclude processing is <emph>not</emph> invoked.</p><p>Except as explicitly defined, the precise process used to construct the XDM instance is <termref def="implementation-defined">implementation-defined</termref>. In particular, it is implementation-defined whether
            an XML 1.0 or XML 1.1 parser is used.</p><p>The document URI of the returned node is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p><p>The function is <emph>not</emph>
            <termref def="dt-deterministic">deterministic</termref>: that is, if the function is called
            twice with the same arguments, it is <termref def="implementation-dependent">implementation-dependent</termref> whether the same node is returned on both
            occasions.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0006"/> if the content of
               <code nobreak="false">$value</code> is not a well-formed external general parsed entity, if it contains
            entity references other than references to predefined entities, or if a document that
            incorporates this well-formed parsed entity would not be namespace-well-formed.</p></def></gitem><gitem><label>Notes</label><def><note><p>See also the notes for the <function>fn:parse-xml</function> function.</p><p>The main differences between <function>fn:parse-xml</function> and
               <function>fn:parse-xml-fragment</function> are that for <function>fn:parse-xml</function>, the
            children of the resulting document node must contain exactly one element node and no
            text nodes, wheras for <function>fn:parse-xml-fragment</function>, the resulting document node
            can have any number (including zero) of element and text nodes among its children. An
            additional difference is that the <emph>text declaration</emph> at the start of an
            external entity has slightly different syntax from the <emph>XML declaration</emph> at
            the start of a well-formed document.</p><p>Note that all whitespace outside the <emph>text declaration</emph> is significant,
            including whitespace that precedes the first element node, unless the <code nobreak="false">strip-space</code>
            option is set.</p><p>One use case for this function is to handle XML fragments stored in databases, which
            frequently allow zero-or-more top level element nodes. Another use case is to parse the
            contents of a <code nobreak="false">CDATA</code> section embedded within another XML document.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-xml-fragment("&lt;alpha&gt;abcd&lt;/alpha&gt;&lt;beta&gt;abcd&lt;/beta&gt;")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>A newly created document node, having two elements named <code nobreak="false">alpha</code>
               and <code nobreak="false">beta</code> as its children; each of these elements in turn is the parent
               of a text node.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-xml-fragment("He was &lt;i&gt;so&lt;/i&gt; kind")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>A newly created document node having three children: a text node whose string
               value is <code nobreak="false">"He was "</code>, an element node named <code nobreak="false">i</code> having a child
               text node with string value <code nobreak="false">"so"</code>, and a text node whose string value is
                  <code nobreak="false">" kind"</code>.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-xml-fragment("")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>A document node having
               no children.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-xml-fragment(" ")</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>A document node whose
               children comprise a single text node whose string value is a single space.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-xml-fragment(" ", { "strip-space": true() })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>A document node having no children.</p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">parse-xml-fragment('&lt;?xml version="1.0" encoding="UTF-8"
                  standalone="yes"?&gt;&lt;a/&gt;')</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>Raises error FODC0006.</p><p><emph>(The <code nobreak="false">standalone</code> keyword is not permitted in the text
               declaration that appears at the start of an external general parsed entity. Thus, it
               is not the case that any input accepted by the <function>fn:parse-xml</function> function
               will also be accepted by the <function>fn:parse-xml-fragment</function>.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-serialize"><head>fn:serialize</head><changes><change PR="2259" date="2025-11-03" issue="938">A new parameter <code nobreak="false">canonical</code> is available to give control
            over serialization of XML, XHTML, and JSON.</change></changes><glist><gitem><label>Summary</label><def><p>This function serializes the supplied input sequence <code nobreak="false">$input</code> as described in
               <bibref ref="xslt-xquery-serialization-31"/>, returning the serialized representation
            of the sequence as a string.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="serialize" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="options" type="(element(output:serialization-parameters) | map(*))?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The value of the first argument <code nobreak="false">$input</code> acts as the input sequence to the
            serialization process, which starts with sequence normalization.</p><p>The second argument <code nobreak="false">$options</code> provides serialization parameters.
            These may be supplied in either  of two forms:</p><olist><item><p>As an <code nobreak="false">output:serialization-parameters</code>
               element, having the format described in <xspecref spec="SER31" ref="serparams-in-xdm-instance"/>. In this case the type of the supplied
               argument must match the required type <code nobreak="false">element(output:serialization-parameters)</code>.</p></item><item><p>As a map. In this case the type of the supplied argument must match the required type <code nobreak="false">map(*)</code></p></item></olist><p>The single-argument version of this function has the same effect as the two-argument
            version called with <code nobreak="false">$options</code> set to the empty sequence. This in turn is the
            same as the effect of passing an <code nobreak="false">output:serialization-parameters</code> element
            with no child elements.</p><p>The final stage of serialization, that is, encoding, is skipped. If the serializer does
            not allow this phase to be skipped, then the sequence of octets returned by the
            serializer is decoded into a string by reversing the character encoding performed in the
            final stage.</p><p>If the second argument is omitted, or is supplied in the form of an <code nobreak="false">output:serialization-parameters</code>
         element, then the values of any serialization parameters that are not explicitly specified is <termref def="implementation-defined">implementation-defined</termref>,
         and may depend on the context.</p><p>If the second argument is supplied as a map, then the <termref def="option-parameter-conventions">option parameter conventions</termref>
         apply. In this case:</p><olist><item><p>Each entry in the map defines one serialization parameter.</p></item><item><p>The key of the entry is an <code nobreak="false">xs:string</code> value in the cases of parameter names defined in these specifications, or an
            <code nobreak="false">xs:QName</code> (with non-absent namespace) in the case of implementation-defined serialization parameters.</p></item><item><p>The required type of each parameter, and its default value, are defined by the following table. The default
            value is used when the map contains no entry for the parameter in question, and also when an entry is present, with the
            empty sequence as its value. The table also indicates how the value of the map entry is to be interpreted in cases
            where further explanation is needed.</p></item></olist><table role="no-code-break data"><thead><tr><th rowspan="1" colspan="1">Parameter</th><th rowspan="1" colspan="1">Required type</th><th rowspan="1" colspan="1">Interpretation</th><th rowspan="1" colspan="1">Default Value</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">allow-duplicate-names</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">no</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">byte-order-mark</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">no</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">canonical</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true()</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false()</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">no</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">cdata-section-elements</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:QName*</code>
                  </td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">
                     <code nobreak="false">()</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">doctype-public</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:string?</code>
                  </td><td rowspan="1" colspan="1">Zero-length string and <code nobreak="false">()</code> both represent <code nobreak="false">"absent"</code></td><td rowspan="1" colspan="1">absent</td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">doctype-system</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:string?</code>
                  </td><td rowspan="1" colspan="1">Zero-length string and <code nobreak="false">()</code> both represent <code nobreak="false">"absent"</code></td><td rowspan="1" colspan="1">absent</td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">encoding</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:string?</code>
                  </td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">
                     <code nobreak="false">UTF-8</code>
                  </td></tr><tr diff="add" at="2023-03-31"><td rowspan="1" colspan="1">
                     <code nobreak="false">escape-solidus</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">yes</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">escape-uri-attributes</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">yes</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">html-version</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:decimal?</code>
                  </td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">
                     <code nobreak="false">5</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">include-content-type</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">yes</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">indent</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">no</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">item-delimiter</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:string?</code>
                  </td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">absent</td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">json-lines</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">no</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">json-node-output-method</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">(xs:string | xs:QName)?</code>
                  </td><td rowspan="1" colspan="1">See Notes 1, 2</td><td rowspan="1" colspan="1">
                     <code nobreak="false">xml</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">media-type</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:string?</code>
                  </td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">(a media type suitable for the chosen <code nobreak="false">method</code>)</td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">method</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">(xs:string | xs:QName)?</code>
                  </td><td rowspan="1" colspan="1">See Notes 1, 2</td><td rowspan="1" colspan="1">
                     <code nobreak="false">xml</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">normalization-form</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:string?</code>
                  </td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">
                     <code nobreak="false">none</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">omit-xml-declaration</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">yes</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">standalone</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code>, <code nobreak="false">()</code> means <code nobreak="false">"omit"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">omit</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">suppress-indentation</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:QName*</code>
                  </td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">
                     <code nobreak="false">()</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">undeclare-prefixes</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:boolean?</code>
                  </td><td rowspan="1" colspan="1"><code nobreak="false">true</code> means <code nobreak="false">"yes"</code>, <code nobreak="false">false</code> means <code nobreak="false">"no"</code></td><td rowspan="1" colspan="1">
                     <code nobreak="false">no</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">use-character-maps</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">map(xs:string, xs:string)?</code>
                  </td><td rowspan="1" colspan="1">See Note 3</td><td rowspan="1" colspan="1">
                     <code nobreak="false">{}</code>
                  </td></tr><tr><td rowspan="1" colspan="1">
                     <code nobreak="false">version</code>
                  </td><td rowspan="1" colspan="1">
                     <code nobreak="false">xs:string?</code>
                  </td><td rowspan="1" colspan="1"/><td rowspan="1" colspan="1">
                     <code nobreak="false">1.0</code>
                  </td></tr></tbody></table><p>Notes to the table:</p><olist><item><p>The notation <code nobreak="false">(A | B)</code> represents a union type whose member types are <code nobreak="false">A</code>
            and <code nobreak="false">B</code>.</p></item><item><p>If an <code nobreak="false">xs:QName</code> is supplied <phrase>for the <code nobreak="false">method</code> or <code nobreak="false">json-node-output-method</code> 
               options,</phrase> then it must have a non-absent namespace URI. This
            means that system-defined serialization methods such as <code nobreak="false">xml</code> and <code nobreak="false">json</code>
            are defined as strings, not as <code nobreak="false">xs:QName</code> values.</p></item><item><p><phrase>For the <code nobreak="false">use-character-maps</code> option</phrase>, the value is a map, whose keys 
               are the characters to be mapped (as <code nobreak="false">xs:string</code> instances),
            and whose corresponding values are the strings to be substituted for these characters. 
            </p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>A type error <xerrorref spec="XP" class="TY" code="0004"/> occurs if the <code nobreak="false">$options</code> argument
            is present and does not match either of the types <code nobreak="false">element(output:serialization-parameters)?</code>
         or <code nobreak="false">map(*)</code>.</p><note><p>This is defined as a type error so that it can be enforced via the function signature by implementations
         that generalize the type system in a suitable way.</p></note><p>If the host language makes serialization an optional feature and the implementation does
            not support serialization, then a dynamic error <errorref class="DC" code="0010"/> is
            raised.</p><p>When the second argument is supplied as a map, 
            and the supplied value is of the wrong type for the particular parameter, for example if the value of <code nobreak="false">indent</code>
         is a string rather than a boolean, then as defined by the <termref def="option-parameter-conventions">option parameter conventions</termref>,
         a type error <xerrorref spec="XP" class="TY" code="0004"/> is raised. 
         If the value is of the correct type, but does not satisfy the rules for that
         parameter defined in <bibref ref="xslt-xquery-serialization-31"/>, then a dynamic error 
         <xerrorref spec="SER31" class="PM" code="0016"/> is raised. (For example, this occurs if the map supplied to
         <code nobreak="false">use-character-maps</code> includes a key that is a string whose length is not one (1)).</p><p>If any serialization error occurs, including the detection of an invalid value for a
            serialization parameter as described above, this results in the <function>fn:serialize</function> call failing with
            a dynamic error.</p></def></gitem><gitem><label>Notes</label><def><note><p>One use case for this function arises when there is a need to construct an XML document
            containing nested XML documents within a CDATA section (or on occasions within a
            comment). See <function>fn:parse-xml</function> for further details.</p><p>Another use case arises when there is a need to call an extension function that expects
            a lexical XML document as input.</p><p>Another use case for this function is serializing instances of the data model into a human
            readable format for the purposes of debugging. Using the <xspecref spec="SER31" ref="adaptive-output"/> by specifying it as the output method defined in the second argument via 
            <code nobreak="false">output:serialization-parameters</code>, allows for serializing any valid
            XDM instance without raising a serialization error.</p><p>There are also use cases where the application wants to post-process the output of a
            query or transformation, for example by adding an internal DTD subset, or by inserting
            proprietary markup delimiters such as the <code nobreak="false">&lt;% ... %&gt;</code> used by some
            templating languages.</p><p>The ability to specify the serialization parameters in an <code nobreak="false">output:serialization-parameters</code>
         element provides backwards compatibility with the 3.0 version of this specification; the ability to
         use a map takes advantage of new features in the 3.1 version. The default parameter values are
         implementation-defined when an <code nobreak="false">output:serialization-parameters</code>
            element is used (or when the argument is omitted), but are fixed by this specification in the
         case where a map (including the empty map) is supplied for the argument.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $params := &lt;output:serialization-parameters 
    xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization"&gt;
  &lt;output:omit-xml-declaration value="yes"/&gt;
&lt;/output:serialization-parameters&gt;
         </eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $data := &lt;a b="3"/&gt;
         </eg></td></tr></tbody></table><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>Given the variables:</p></td></tr><tr><td colspan="2" rowspan="1"><p>The following call might produce the output shown:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">serialize($data, $params)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">'&lt;a b="3"/&gt;'</code></p></td></tr><tr><td colspan="2" rowspan="1"><p>The following call would also produce the output shown (though the second argument could equally well be supplied
               as the empty map (<code nobreak="false">{}</code>), since both parameters are given their default values):</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">serialize(
  $data,
  { "method": "xml", "omit-xml-declaration": true() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'&lt;a b="3"/&gt;'</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">serialize({ "a": "AB", "b": "BC" }, { "method": "adaptive" })</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">'{"a":"AB","b":"BC"}'</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
serialize(
  array { "a", 3, attribute test { "true" } },
  { "method": "adaptive" 
})
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">'["a",3,test="true"]'</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="xsd-validation"><head>XSD validation</head><changes><change issue="2029" PR="2030" date="2025-05-28">
                     This description of the XSD validation process was previously found (with some duplication)
                     in the XQuery and XSLT specifications; those specifications now reference this description.
                     As a side-effects, the descriptions of the process in XQuery and XSLT are better aligned.
                  </change></changes><p>This section describes a process called <term>XSD validation</term>, which validates
                  a supplied node against a supplied XSD schema. 
                  The validation process refers to the process defined in <bibref ref="xmlschema-1"/> or <bibref ref="xmlschema11-1"/>.</p><p>The validation process takes the following inputs:</p><ulist><item><p>A schema to be used for validation, 
                     called the <term>effective schema</term>.</p></item><item><p>A boolean indicating whether any <code nobreak="false">xsi:schemaLocation</code>
                  or <code nobreak="false">xsi:noNamespaceSchemaLocation</code> attributes are to be taken
                  into consideration.</p></item><item><p>A document, element, or attribute node to be validated;
                  this is called the <term>operand node</term>.</p></item><item><p>A validation mode, which is one of <code nobreak="false">strict</code>
                  <code nobreak="false">lax</code>, or <code nobreak="false">by-type</code>.</p><note><p>XSLT also allows the value <code nobreak="false">strip</code>, but
                     this does not invoke validation (instead, it invokes stripping
                     of existing type annotations, and re-annotation of nodes as 
                        <code nobreak="false">xs:untyped</code>.)</p></note></item><item><p>If the validation mode is <code nobreak="false">by-type</code>, then
                  a schema type to be used for validating the operand node.
                  This may be any simple or complex type present in the effective
                  schema: it must not be <code nobreak="false">xs:untyped</code> or <code nobreak="false">xs:untypedAtomic</code>.</p><note><p>An XQuery <code nobreak="false">ValidateExpr</code> allows the type to be
                  specified as <code nobreak="false">xs:untyped</code> or <code nobreak="false">xs:untypedAtomic</code>,
                  but this does not invoke validation (instead, it invokes stripping of
                  existing type annotations and re-annotation of nodes as untyped.)</p></note></item></ulist><p>The output of the validation process comprises one or more of the following:</p><ulist><item><p>A boolean indicating whether the operand node was found to be
                  valid.</p></item><item><p>If the operand node was found to be valid, a deep copy of
                  the operand node augmented with <termref def="dt-type-annotation">type annotations</termref> 
                     corresponding to the types against which they were validated, the copies
                     may also include expanded values for element and attribute defaults
                     defined in the schema.</p><p>This creates a new node with its own identity and with no parent.</p><p>The base URI property of every node in the resulting XDM tree is the same as
                     the base URI property of the corresponding node in the input tree. </p></item><item><p>If the operand node was not found to be valid, then optionally,
                  a set of error diagnostics in implementation-defined format.</p></item></ulist><p>The operand node must be one of:</p><ulist><item><p>An element node</p></item><item><p>An attribute node</p></item><item><p>A well-formed document node, that is, a document node
                  having among its children exactly one element node and zero or more comment
                  and processing instruction nodes.</p></item></ulist><p>The term <term>validation root</term> is used to refer to the operand node
               if it is an element or attribute node, or to the single element child of the
               operand node when the operand node is a document node.</p><p>Note that a <term>schema</term> is defined as a collection of schema components (for example,
               element and attribute declarations, complex and simple type definitions). In some cases
               the schema that is used is the set of schema components found in the <xtermref spec="XP40" ref="dt-issd">in-scope schema definitions</xtermref>, but this is not the only
               possibility.</p><p>The result of the validation process is defined by the following rules.</p><olist><item><p>The invoking application determines whether the validity assessment
                     process takes account of any <code nobreak="false">xsi:schemaLocation</code> or <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
                     attributes in the tree being validated. If it does so, then it <rfc2119>should</rfc2119>
                     adhere to the following rules:</p><olist><item><p>Any schema loaded using these attributes must be 
                           <xtermref spec="DM40" ref="dt-schema-compatible">compatible</xtermref> 
                        with the existing <term>effective schema</term>.</p></item><item><p>Any schema loaded using these attributes must not override
                        or redefine any schema components in the effective schema.</p></item><item><p>Any schema components loaded using this mechanism must be
                        used for this validity assessment only, and must not 
                        affect the outcome of any subsequent validity assessments of other documents.</p><note><p>A processor may choose to cache such schema components but the existence
                        of such a cache should only affect performance, not the validation outcome.</p></note></item></olist><p>A consequence of validating a document using schema components that are not 
                     in the static context is that nodes may be annotated with types 
                     that are not in the static context. But the rules for
                     <xtermref spec="DM40" ref="dt-schema-compatible">schema compatibility</xtermref>
                     mean that this is not a problem.</p></item><item><p>If the instance being validated contains any <code nobreak="false">xml:id</code> attributes, 
                     such attributes are validated against the type 
                     <code nobreak="false">xs:ID</code>, making the containing element 
                     eligible as a target for the <function>id</function> function.
                     Uniqueness checking of elements and attributes typed as <code nobreak="false">xs:ID</code>,
                     however, is carried out only if the operand node is a document node.
                 </p></item><item><p> If the operand node is a document node:</p><olist><item><p>The children of the document node <rfc2119>must</rfc2119>
                        consist of exactly one element node and zero or more comment and
                        processing instruction nodes, in any order.</p></item><item><p>The element node child is validated, as described below.</p></item><item><p>The validation rule <quote>Validation Root Valid (ID/IDREF)</quote> is
                        applied to the single element node child of the document node. This means
                        that validation will fail if there are non-unique ID values or dangling
                        IDREF values in the document tree.</p><note><p>This rule is <emph>not</emph> applied when the operand node
                     is an element or attribute node.</p></note></item><item><p>There is no check that the tree contains unparsed entities whose names match
                        the values of nodes of type <code nobreak="false">xs:ENTITY</code> or
                           <code nobreak="false">xs:ENTITIES</code>. This is because it is not possible
                        (either in XSLT or XQuery) to construct a tree containing
                        unparsed entities. It is possible to
                        add unparsed entity declarations to the result document by referencing a
                        suitable DOCTYPE during serialization.</p></item><item><p>All other children of the document node (comments and processing
                        instructions) are copied unchanged, and the results become the
                     children of a new document node, which is returned as the validation result.</p></item></olist></item><item><p>If the operand node is an element node, then:</p><olist><item><p>For specification purposes, because the XSD specifications
                      require the input document to be expressed as an XML Information Set
                     (<bibref ref="XINFO"/>), the operand node is first converted to an Infoset according 
                        to the “Infoset Mapping” rules
                        defined in <bibref ref="xpath-datamodel-40"/>. Note that this process discards any existing <termref def="dt-type-annotation">type annotations</termref>.</p><p>Validity assessment is carried out on the root element
                       information item of the resulting Infoset, using the supplied
                       schema. The process of validation applies recursively to contained
                       elements and attributes to the extent required by the supplied
                       schema. </p><note><p>A practical implementation is unlikely to perform
                     any physical conversion, but the process is defined this way in order
                     to align with the XSD specification.</p></note></item><item><p>If the validation mode is <code nobreak="false">by-type</code>, then
                     Schema-validity assessment is
                        carried out according to the rules defined in <bibref ref="xmlschema-1"/> or <bibref ref="xmlschema11-1"/> Part 1, section 3.3.4 "Element
                        Declaration Validation Rules", “Validation Rule: Schema-Validity Assessment (Element)”, 
                        clauses 1.2 and 2, using this type definition as the
                        <quote>processor-stipulated type definition</quote> for validation.</p></item><item><p>If validation mode is <code nobreak="false">strict</code>, then 
                           strict validation is carried out as described in 
                           <bibref ref="xmlschema-1"/> Part 1, section 5.2, “Assessing Schema-Validity”, item
                       2, or its counterpart in XSD 1.1. This means that the
                           root element information item in the Infoset must 
                           either:</p><olist><item><p>have a name that matches a
                       top-level element declaration in the effective schema, or</p></item><item><p>have an <code nobreak="false">xsi:type</code> attribute
                           whose value matches the name of a top-level type definition
                           in the effective schema</p></item></olist><p>If there is no such element declaration or type definition, the element
                          is assessed as invalid.</p></item><item><p>If validation mode is <code nobreak="false">lax</code>, then schema-validity
                       assessment is carried out in accordance with <bibref ref="xmlschema-1"/> Part 1, section 5.2, “Assessing Schema-Validity”,
                       item 3, or its counterpart in XSD 1.1.</p><p>If validation mode is <code nobreak="false">lax</code> and the root element
                           information item has neither a top-level element
                           declaration nor an <code nobreak="false">xsi:type</code> attribute, XSD 1.0
                           and XSD 1.1 define the recursive checking of children
                           and attributes as optional. This specification prescribes that this
                           recursive checking is required.</p><note><p>This means, for example, that when an instance document
                        is structured as having an envelope in one namespace wrapping
                        a payload in a different namespaces, and when schema definitions are
                        available for the payload but not for the envelope, lax validation
                        of the envelope may trigger validation of the payload.</p></note></item><item><p>If the operand node is an element node, the validation rules named
                   “Validation Root Valid (ID/IDREF)” are not applied. This means that document-level constraints
                   relating to uniqueness and referential integrity are not enforced.</p></item><item><p>There is no check that the document contains unparsed entities whose names match the
                   values of nodes of type <code nobreak="false">xs:ENTITY</code> or <code nobreak="false">xs:ENTITIES</code>.</p></item></olist></item><item><p>If the operand node is an attribute node, in particular when it is a parentless
                   attribute node, then validation cannot be defined
                directly in terms of the XSD-defined validation process. Instead, 
                conceptually, a copy of the attribute is first added to an element
                     node that is created for the purpose, and namespace fixup 
                     is performed on this element node to ensure that it has an in-scope 
                     namespace binding for the prefix and namespace of the attribute name. The name of this
                     element is of no consequence, but it must be the same as the name of a
                     synthesized element declaration of the form:</p><eg role="xslt-instruction" xml:space="preserve">&lt;xs:element name="E"&gt;
  &lt;xs:complexType&gt;
    &lt;xs:sequence/&gt;
    &lt;xs:attribute ref="A"/&gt;
  &lt;/xs:complexType&gt;
&lt;/xs:element&gt;</eg><p>where A is the name of the attribute being validated.</p><p>This synthetic element is then validated using the procedure given above for
                     validating elements, and if it is found to be valid, a copy of the validated
                     attribute is made, retaining its <termref def="dt-type-annotation">type
                        annotation</termref>, but detaching it from the containing element (and
                     thus, from any in-scope namespace bindings).</p><p>The XDM data model does not permit an attribute node with no parent to have a
                     typed value that includes a namespace-qualified name, that is, a value whose
                     type is derived from <code nobreak="false">xs:QName</code> or <code nobreak="false">xs:NOTATION</code>. This
                     restriction is imposed because these types rely on the in-scope namespaces of a
                     containing element to resolve namespace prefixes. Therefore, 
                     a parentless attribute is considered to be invalid against such a type.</p></item><item><p>The outcome of the validation expression depends on the
            <code nobreak="false">validity</code> property of the root element information item in the PSVI that results
            from the XSD validation process.</p><olist><item><p>If the <code nobreak="false">validity</code> property of the root element
                    information item is <code nobreak="false">valid</code>,

                    or if validation mode is
                    <code nobreak="false">lax</code> and the <code nobreak="false">validity</code> property of the root
                    element information item is <code nobreak="false">notKnown</code>,

                    the PSVI is converted back into a data model instance
                    as described in <bibref ref="xpath-datamodel-40"/> Section
                    3.3, “Construction from a PSVI”.

                    The resulting node (a new node of the same kind as the operand node)
                    is returned as the result of the <code nobreak="false">validate</code>
                    expression.</p><p>Otherwise, the operand node is deemed invalid.</p></item></olist></item></olist><note><p>During conversion of the PSVI into an XDM instance
        after validation, any element information items whose validity property is <code nobreak="false">notKnown</code> are
        converted into element nodes with <termref def="dt-type-annotation">type annotation</termref>
               <code nobreak="false">xs:anyType</code>, and any attribute information items whose validity property is
        <code nobreak="false">notKnown</code> are converted into attribute nodes with <termref def="dt-type-annotation">type annotation</termref>
               <code nobreak="false">xs:untypedAtomic</code>, as described in <xspecref spec="DM40" ref="PSVI2NodeTypes"/>.
    </p></note></div3><div3 id="func-xsd-validator"><head>fn:xsd-validator</head><changes><change issue="1271" PR="1933" date="2025-04-29">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Given an XSD schema, delivers a function item that can be invoked to validate a document, element, or attribute node
            against this schema.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="xsd-validator" return-type="function((document-node(*) | element() | attribute())?) as record(is-valid as xs:boolean, typed-node? as node(), error-details? as record(*)*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The <function>fn:xsd-validator</function> function returns a function item that can be used to validate a
        document node, element node, or attribute node with respect to a supplied schema.</p><p>The details of how the schema is assembled, and the way it is used, are defined by the supplied <code nobreak="false">$options</code>.
            If the <code nobreak="false">$options</code> argument is empty, the effect is to use the schema components from the
            static context of the call on <function>fn:xsd-validator</function>. In the general case, however, the schema 
            used for validation may include components from any or all of the following:</p><ulist><item><p>The static context of the function call</p></item><item><p>Explicitly supplied schema documents</p></item><item><p>Schema components referenced in <code nobreak="false">xsi:schemaLocation</code> and <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
            attributes within the instance document being validated.</p></item></ulist><p>More details of schema assembly appear below. 
            Taken together, the assembled components must constitute a valid schema.</p><p>The function is designed to separate the process of assembling a schema from the process of performing instance
            validation. However, if the schema is to include components identified in
            <code nobreak="false">xsi:schemaLocation</code> and <code nobreak="false">xsi:noNamespaceSchemaLocation</code> attributes, then the process of
            assembling the schema cannot be completed until the instance document is available.</p><p>The options recognized are as follows. The <termref def="option-parameter-conventions"/> apply.</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="trusted" type="xs:boolean" occur="opt"/><arg name="use-imported-schema" type="xs:boolean" occur="opt"/><arg name="schema" type="element(xs:schema)*" occur="opt"/><arg name="target-namespace" type="xs:anyURI*" occur="opt"/><arg name="schema-location" type="xs:anyURI*" occur="opt"/><arg name="use-xsi-schema-location" type="xs:boolean" occur="opt"/><arg name="xsd-version" type="xs:decimal" occur="opt"/><arg name="validation-mode" type="xs:string" occur="opt"/><arg name="type" type="xs:QName?" occur="opt"/><arg name="return-typed-node" type="xs:boolean" occur="opt"/><arg name="return-error-details" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="3" colspan="1"><p><code nobreak="false">trusted?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Indicates whether the validation process may cause 
                  external resources to be fetched (including, for example, documents 
                  referenced using the <code nobreak="false">schema-location</code>
                  property, or <code nobreak="false">xsi:schemaLocation</code> attributes within
                  the document being validated).<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false()</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The validation process may retrieve external
                     resources.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">The validation process must not retrieve any 
                     external resources unless access to these resources has been explicitly
                     enabled.
                  </td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">use-imported-schema?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">If true, the schema to be used for validation includes the schema components
                  available in the static context of the function call. If false, these components
                  are not used.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">schema?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">A list of XDM nodes containing XSD schema documents to be used
               for validation.<ulist><item><p><term>Type: </term><code nobreak="false">element(xs:schema)*</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">target-namespace?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">A list of target namespaces identifying schema components to be used for
               validation. The way in which the processor locates schema components for the specified
               target namespaces is <termref def="implementation-defined"/>. A zero-length string denotes
               a no-namespace schema.<ulist><item><p><term>Type: </term><code nobreak="false">xs:anyURI*</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">schema-location?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">A list of locations of XSD schema documents to be used to assemble a schema.
               Any relative URIs are resolved relative to the base URI of the function call.
               Access to the schema documents at these locations is allowed regardless of the value
               of the <code nobreak="false">trusted</code> option; access to indirectly referenced schema documents
               (for example, using <code nobreak="false">xs:include</code> is allowed only if the <code nobreak="false">trusted</code>
               option is set to <code nobreak="false">true</code>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:anyURI*</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">use-xsi-schema-location?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">If true, the schema to be used for validation includes any schema documents
               referenced by <code nobreak="false">xsi:schemaLocation</code> or <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
               attributes in the instance document being validated. If false, these attributes are ignored.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">xsd-version?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">Set to the decimal value 1.0 or 1.1 to indicate which version of XSD is to be used.
               The default is <termref def="implementation-defined"/>. A processor may use a later version
               of XSD than the version requested, but must not use an earlier version.<ulist><item><p><term>Type: </term><code nobreak="false">xs:decimal</code></p></item></ulist></td></tr><tr><td rowspan="4" colspan="1"><p><code nobreak="false">validation-mode?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">The validation mode.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">strict</code></td><td rowspan="1" colspan="1">Validates the input using the element or attribute declaration for the
                  operand node. This element or attribute declaration must exist. This is the default
                  when the <code nobreak="false">type</code> option is absent.</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">lax</code></td><td rowspan="1" colspan="1">Validates the input using the element or attribute declaration for the
                  operand node, if it exists.</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">by-type</code></td><td rowspan="1" colspan="1">Validates the input using the supplied governing type. This is the
                  default when the <code nobreak="false">type</code> option is present.</td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">type?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">Establishes the governing type for validation. The type must be present
               in the assembled schema.<ulist><item><p><term>Type: </term><code nobreak="false">xs:QName?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">return-typed-node?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">If true, the result of the generated validation function, when validation
                  is successful, includes the property <code nobreak="false">typed-node</code> which contains a copy of the
                  target node augmented with type annotations and expanded default values. If false, the typed
                  node is not included in the result. If a node containing type annotations is to be returned,
                  then the schema used for validation must be compatible with all other schemas used within
                  the same query or stylesheet, as described in <xspecref spec="DM40" ref="schema-consistency"/>;
                  this is to ensure that the type annotations in the validated document have a consistent
                  interpretation.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">return-error-details?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">If true, the result of the generated validation function, when validation
                  is unsuccessful, includes detailed information about the nature of the validity errors
                  that were found. If false, the result only includes an indication that the document
                  was invalid. Note that setting the value to false means that validation can complete
                  as soon as the first error is found.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr></tbody></table><p>The first task of the function is to assemble a schema (that is, a collection of schema
         components). Schema components can come from a number of sources, and a schema can be assembled
         from more than one source, provided that the total collection of components comprises a valid schema:
         the main thing that will prevent this is if two sources contain conflicting definitions of the
         same named component.</p><ulist><item><p>The default is to use the in-scope schema components from the static context
            of the function call.</p></item><item><p>Instead, or in addition, schema components may be loaded explictly
            for this validator. Supplementary schema components may be requested in a number of
            ways:</p><ulist><item><p>The <code nobreak="false">schema-location</code> option can specify one or more URIs that
               are interpreted as locations for source XSD schema documents, which are then
               assembled into a schema as described in the XSD specifications.</p></item><item><p>The <code nobreak="false">schema</code> option can be used to identify one or more
               <code nobreak="false">xs:schema</code> element nodes holding source schema documents. This allows
               a schema to be constructed dynamically by the application, or to be held as
               a global variable in the source code of a query or stylesheet module.</p></item><item><p>The <code nobreak="false">target-namespace</code> option can be used to supply
               the target namespaces of additional schema components that are known to the
               system or that are made available using some external mechanism. For example,
               the system might have built-in schemas for common namespaces such as
               the <code nobreak="false">xml</code>, <code nobreak="false">fn</code>, or <code nobreak="false">xlink</code> namespaces,
               or it might have a mechanism allowing schemas for a particular namespace
               to be registered using an external API or configuration mechanism.</p></item></ulist></item><item><p>The <code nobreak="false">use-xsi-schema-location</code> also allows the application
            to request that schema documents referenced from <code nobreak="false">xsi:schemaLocation</code>
            or <code nobreak="false">xsi:noNamespaceSchemaLocation</code> attributes should be included
            in the schema. By default these attributes are ignored.</p></item><item><p>It is acceptable to assemble a schema from more than one of these
            sources. In addition, any of these sources can bring in additional components
            by the use of the XSD directives <code nobreak="false">xsl:include</code> and <code nobreak="false">xsl:import</code>.
            The important constraint is that the result should be a valid schema. This will only
            be the case if the sources used to assemble the schema are 
               <xtermref spec="DM40" ref="dt-schema-compatible">compatible</xtermref>
            with each other: see <xspecref spec="DM40" ref="schema-consistency"/>.</p></item><item><p>The XSD specification allows a schema to be used for validation even when 
             it contains unresolved
             references to absent schema components. It is <termref def="implementation-defined"/> whether
             this function allows the schema to be incomplete in this way. For example,
            some processors might allow validation using a schema in which an element declaration
            contains a reference to a type declaration that is not present in the schema, provided
            that the element declaration is never needed in the course of a particular validation
            episode.</p></item></ulist><p>Having assembled a schema, the next task is to validate a supplied node (and the subtree
            rooted at that node).</p><note><p>This description is a deliberate simplification. If the <code nobreak="false">use-xsi-schema-location</code>
         option is <code nobreak="false">true</code>, then assembly of the schema is not completed until the instance document
         is available, and in practice overlaps with the validation process.</p></note><p>The <function>xsd-validator</function> function returns a function item (call it <var>V</var>)
         with the following characteristics:</p><ulist><item><p><var>V</var> has an arity of one. Call the value of the supplied argument
               <code nobreak="false">$target</code>. The required type of <code nobreak="false">$target</code>
            is <code nobreak="false">(document-node(*) | element() | attribute())?</code>: 
               that is, it accepts either a well-formed
            document node, or an element node, or an attribute node, or the empty sequence.</p></item><item><p>If the argument is the empty sequence
            then the result of <var>V</var> is also the empty sequence.</p></item><item><p>In other cases, the result of a call on <var>V</var> is a record 
               containing the following fields:</p><ulist><item><p><code nobreak="false">is-valid as xs:boolean</code>. This field is always present, and indicates
                  whether the supplied <code nobreak="false">$target</code> node was found to be valid against the schema.
                  The value is <code nobreak="false">true</code> if either (a) the validation outcome was <code nobreak="false">valid</code>, or
                  (b) lax validation was requested and the validation outcome was <code nobreak="false">notKnown</code>.
                  In other cases it is <code nobreak="false">false</code>.</p></item><item><p><code nobreak="false">typed-node as (document-node(*) | element() | attribute())</code>. 
                     This field is present
                  only when (a) the option <code nobreak="false">return-typed-node</code> was set (explicitly or implicitly)
                  to <code nobreak="false">true</code>, and (b) the value of the <code nobreak="false">is-valid</code> field is <code nobreak="false">true</code>. 
                     It represents the root of a tree that is a deep copy of the input tree, 
                     augmented with type annotations and default values.</p></item><item><p><code nobreak="false">error-details as map(*)*</code>. This field is present only when (a) the option
                  <code nobreak="false">return-error-details</code> was set 
                  to <code nobreak="false">true</code>, and (b) the supplied document was found to be invalid. The value is a sequence
                  of maps, each containing details of one invalidity that was found. The precise details of the
                  invalidities are <termref def="implementation-defined"/>, but they <rfc2119>may</rfc2119> include 
                  the following fields, if the information is available:</p><ulist><item><p><code nobreak="false">message</code>. A string containing the text of an error message, intended
                     for a human reader.</p></item><item><p><code nobreak="false">rule</code>. A reference to the rule in the XSD specification that was violated.
                     This is a string comprising four parts separated by the character <char>U+007C</char>:</p><ulist><item><p>"1.0" or "1.1" indicating whether the reference is to the XSD 1.0 or 1.1 specification.</p></item><item><p>"1" or "2" indicating whether the reference is to part 1 or part 2 of the specification.</p></item><item><p>The name of the validation rule (for example "Datatype Valid").</p></item><item><p>The clause number within that validation rule (for example "2.3").</p></item></ulist><p>For example, if an attribute is declared to be of type <code nobreak="false">xs:integer</code>, but the
                        actual value is not in the lexical space of <code nobreak="false">xs:integer</code>, the value of <code nobreak="false">rule</code>
                        might be <code nobreak="false">"1.1|2|Datatype Valid|2.1"</code>.</p></item><item><p><code nobreak="false">node</code>. The node that was found to be invalid. Note that when a containing element 
                        <var>C</var> is invalid because a child element <var>D</var> is not allowed by its content
                        model, the invalid node is <var>C</var>, not <var>D</var>.</p></item><item><p><code nobreak="false">error-node</code>. The node whose presence led to detection of the invalidity. In the
                     above example, this would be <var>D</var>.</p></item><item><p><code nobreak="false">error-uri</code>. The URI of the XML entity in which the error was detected.</p></item><item><p><code nobreak="false">line-number</code>. The line number where the error was detected, within its external entity.</p></item><item><p><code nobreak="false">column-number</code>. The column number where the error was detected, within the error line number.</p></item></ulist></item></ulist></item><item><p>The validation is performed as described in <specref ref="xsd-validation"/>, with
               the assembled schema as the effective schema and <code nobreak="false">$target</code> as the operand node.</p></item><item><p>If the <code nobreak="false">use-xsi-schema-location</code> option is <code nobreak="false">true</code> and a failure
               occurs processing an <code nobreak="false">xsi:schemaLocation</code> or <code nobreak="false">xsi:noNamespaceSchemaLocation</code>
               attribute (for example, because a schema document cannot be retrieved, or because the referenced
               schema document is invalid, or because it is incompatible with other schema components) 
               this is treated as an invalidity, not as a dynamic error:
               <var>V</var> returns successfully with <code nobreak="false">is-valid</code> set to <code nobreak="false">false</code>.</p></item><item><p>The function <var>V</var> may fail with a dynamic error if it is not possible to determine whether or not the
               instance document is valid. This may happen, for example, if processor-defined limits are exceeded.</p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0009"/> if the processor is not schema-aware, or if no schema processor with the required capabilities (such as XSD 1.1 support)
         is available.</p><p>A dynamic error is raised <errorref class="DC" code="0015"/> if it is not possible to assemble a valid and consistent schema.</p></def></gitem><gitem><label>Notes</label><def><note><p>Both XQuery and XSLT provide capabilities for XSD-based schema validation in earlier versions of the specifications,
          and those are retained in 4.0. This function provides additional capability:</p><ulist><item><p>It is possible to control validation more precisely, through a wider range of options;</p></item><item><p>It is possible to validate different instance documents against different schemas;</p></item><item><p>Information about any invalidities is made available to the application, rather than simply causing a dynamic error;</p></item><item><p>The capability is provided by means of a function rather than custom syntax, making it easier
             to integrate into an application.</p></item><item><p>The capability is available through XPath alone, and therefore with host languages other than
             XQuery and XSLT.</p></item></ulist><p>Three possible ways of using the function include:</p><ulist><item><p>To simply test whether or not a document is valid against a schema, set the options
             <code nobreak="false">return-typed-node</code> and <code nobreak="false">return-error-details</code> to <code nobreak="false">false</code>,
             and simply test the value of the <code nobreak="false">is-valid</code> field returned when the validation function
             is called.</p></item><item><p>To obtain a typed XDM tree from an input document that is expected to be valid, set the
             option <code nobreak="false">return-typed-node</code> to true. On return from the validation function, test the
             value of the <code nobreak="false">is-valid</code> field; call <function>fn:error</function> if the value is false;
             otherwise use the <code nobreak="false">typed-node</code> property of the result. The main benefit of using a typed
             XDM tree is that it allows static type checking of path expressions: this benefit only applies
             when the schema used for validation is the imported schema used in the static context. However, there
             are cases where validation against a different schema is appropriate, for example when validating the
             result of one query or transformation that is to be used as input to another.</p></item><item><p>To validate an input document and provide feedback to the document author about any validity
             problems that were found, set <code nobreak="false">return-error-details</code> to <code nobreak="false">true</code>. If the result
             of the validation function has <code nobreak="false">is-valid = false()</code>, process the returned <code nobreak="false">error-details</code>.
             The information available for this part of the processing may not be 100% interoperable, though with care it
             should be possible to write the query in such a way that it works with different processors.</p></item></ulist><p>The function has no effect on the static context. Schemas loaded using this function, either directly or
          via the effect of <code nobreak="false">xsi:schemaLocation</code> and <code nobreak="false">xsi:noNamespaceSchemaLocation</code> attributes, are not
          added to the static context and have no effect on any other validation episodes. A processor may cache schema
          components to reduce the cost of processing the same schema repeatedly, but this has no observable effect other than
          on performance.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $schema := 
  &lt;xs:schema&gt;
    &lt;xs:element name="distance" type="xs:decimal"/&gt;
  &lt;/xs:schema&gt;
let $validator := xsd-validator({'schema': $schema})
return ($validator(&lt;distance&gt;8.5&lt;/distance&gt;)?is-valid,
        $validator(&lt;distance&gt;8.5km&lt;/distance&gt;)?is-valid)
                   </eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true(), false()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $schema := 
  &lt;xs:schema&gt;
    &lt;xs:element name="distance" type="xs:decimal"/&gt;
  &lt;/xs:schema&gt;
let $validator := xsd-validator({'schema': $schema})
let $typed-result := $validator(&lt;distance&gt;8.5&lt;/distance&gt;)?typed-node
return $typed-result instance of element(distance, xs:decimal)
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="html-functions"><head>Functions on HTML Data</head><changes><change issue="74 850 1799 1889 1891" PR="259 956" date="2023-01-10">
                  A new function is available for processing input data in HTML format.
               </change></changes><p>This function converts between the lexical representation of HTML and the XDM tree representation.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-html</code></td><td rowspan="1" colspan="1">This function takes as input an HTML document, and returns the
            document node at the root of an XDM tree representing the parsed document.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:html-doc</code></td><td rowspan="1" colspan="1">Reads an external resource containing HTML, and returns the result of parsing the resource as HTML.</td></tr></tbody></table><div3 id="html-xdm-mapping"><head>XDM Mapping from HTML DOM Nodes</head><p>The <function>fn:parse-html</function> function conceptually works in two phases:</p><olist><item><p>The lexical HTML (supplied as a string) is parsed into an HTML DOM
                     as defined by the HTML5 specification: see <bibref ref="html5"/> and
                     <bibref ref="dom-ls"/>.
                  </p></item><item><p>The resulting DOM is converted to an XDM tree as described in this
                  section. This is described by defining the actions of the accessor functions
                  defined in <xspecref spec="DM40" ref="accessors"/>.</p></item></olist><note><p>Because the <bibref ref="dom-ls"/> and <bibref ref="html5"/> are not fixed, it is
                     <termref def="implementation-defined">implementation-defined</termref> which versions are used.</p></note><note><p>An implementation must match the semantics of the mapping described in this section, but
                  the specific way it achieves that is <termref def="implementation-dependent">implementation-dependent</termref>.</p><p>Some possible implementation strategies are:</p><olist><item><p>Parse the HTML to an HTML DOM and then convert the HTML DOM to an XDM node tree.</p></item><item><p>Parse the HTML to an HTML DOM and then implement a wrapper or facade that presents
                     an XDM interface to the HTML DOM.</p></item><item><p>Parse the lexical HTML directly to an XDM node tree, bypassing the HTML DOM.</p></item></olist></note><p>The <bibref ref="dom-ls"/> defines parsing algorithms for two different formats, which it refers to
                  as the HTML and XML serializations (or concrete syntaxes). The XML serialization is an XML document which typically
                  uses the namespace <code nobreak="false">http://www.w3.org/1999/xhtml</code> and the content type
                  <code nobreak="false">application/xhtml+xml</code>, and is popularly referred to as <code nobreak="false">XHTML</code>.
                  The HTML parsing algorithm constructs
                  an HTML DOM <code nobreak="false">HTMLDocument</code> document object for the HTML document. The XHTML parsing
                  algorithm constructs an HTML DOM <code nobreak="false">XMLDocument</code> object for the HTML document, following
                  XML parsing rules. This mapping supports both of these document types.</p><p>The <bibref ref="dom-ls"/> specification defines HTML DOM nodes that are mapped to XDM
                  nodes as follows:</p><olist><item><p>The HTML DOM <code nobreak="false">Document</code> interface maps to <xspecref spec="DM40" ref="DocumentNode"/>.</p></item><item><p>The HTML DOM <code nobreak="false">Element</code> interface maps to <xspecref spec="DM40" ref="ElementNode"/>.
                     But see below for the mapping of an HTML <code nobreak="false">template</code> element.</p></item><item><p>The HTML DOM <code nobreak="false">Attr</code> interface maps to <xspecref spec="DM40" ref="AttributeNode"/>.</p><note><p>Any HTML DOM <code nobreak="false">Attr</code> instances in an HTML DOM <code nobreak="false">HTMLDocument</code> that represent
                        namespace declarations will have been filtered out: see <specref ref="html-attributes-accessor"/>.</p></note></item><item><p>The HTML DOM <code nobreak="false">ProcessingInstruction</code> interface maps to
                        <xspecref spec="DM40" ref="ProcessingInstructionNode"/>.</p><note><p>The HTML parsing algorithm does not generate processing instruction nodes. If encountered
                           they are parsed as comment nodes. The HTML DOM <code nobreak="false">ProcessingInstruction</code>
                           interface is relevant only when the XHTML parsing algorithm is used.</p></note></item><item><p>The HTML DOM <code nobreak="false">Comment</code> interface maps to <xspecref spec="DM40" ref="CommentNode"/>.</p></item><item><p>The HTML DOM <code nobreak="false">Text</code> interface maps to <xspecref spec="DM40" ref="TextNode"/>.
                        Adjacent HTML DOM <code nobreak="false">Text</code> nodes are combined into a single
                        <xspecref spec="DM40" ref="TextNode"/>.</p><note><p>The HTML DOM <code nobreak="false">CDATASection</code> interface is an instance of HTML DOM
                           <code nobreak="false">Text</code>, so CDATA sections also map to <xspecref spec="DM40" ref="TextNode"/>.</p><p>The use of CDATA sections can result in the HTML DOM containing adjacent text nodes,
                        which the mapping to XDM will merge into a single node.</p></note></item><item><p>An HTML <code nobreak="false">template</code> element is mapped to an XDM <code nobreak="false">template</code>
                  element with children corresponding to the children of the HTML DOM <code nobreak="false">DocumentFragment</code>
                  that is the value of the <term>template contents</term> property of the HTML DOM
                  <code nobreak="false">template</code> element.</p><note><p>Given source HTML such as <code nobreak="false">&lt;template&gt;&lt;p&gt;Lorem ipsum&lt;/p&gt;&lt;/template&gt;</code>,
                     the HTML DOM represents the element <code nobreak="false">&lt;p&gt;Lorem ipsum&lt;/p&gt;</code> 
                  not as a child of the <code nobreak="false">template</code> element, but as the child of a free-standing
                  document fragment which is accessible (in the DOM API) as the value of the 
                  <code nobreak="false">template.content</code> property of the element node. The XDM representation produced
                  by the <function>parse-html</function> does not follow this convention: instead, the 
                  element <code nobreak="false">&lt;p&gt;Lorem ipsum&lt;/p&gt;</code> appears as an ordinary child node of the 
                  <code nobreak="false">template</code> element.</p></note></item></olist><note><p>The HTML DOM <code nobreak="false">DocumentFragment</code> interface is not supported as an XML node.
                     There are two places in the HTML DOM where this is used:</p><olist><item><p>The HTML DOM <code nobreak="false">ShadowRoot</code> interface is not present in the main HTML DOM
                           tree. It is only accessible via JavaScript.</p></item><item><p>The <code nobreak="false">template</code> element’s <code nobreak="false">content</code> property contains
                           the child nodes of the <code nobreak="false">template</code> element. The behaviour of this
                           is described above.</p></item></olist><p>If an implementation allows these nodes to be passed in via an API or similar mechanism,
                     their behaviour is <termref def="implementation-defined">implementation-defined</termref>.</p></note><div4 id="html-attributes-accessor"><head>attributes Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-attributes"/>
                  <code nobreak="false">dm:attributes($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Element</code> then the result
                        is the value of the <code nobreak="false">Element.attributes</code> property mapped to a
                        sequence as described below;</p></item><item><p>Otherwise, the result is the empty sequence.</p></item></olist><p>An HTML DOM <code nobreak="false">NamedNodeMap</code> is mapped to a sequence as follows:</p><olist><item><p><code nobreak="false">NamedNodeMap.length</code> is the length of the sequence, where a length
                        of <code nobreak="false">0</code> results in the empty sequence;</p></item><item><p><code nobreak="false">NamedNodeMap.item(n)</code> is the n<sup>th</sup> element of the sequence.</p></item></olist><p>That sequence is then filtered as follows:</p><olist><item><p>If the <code nobreak="false">Attr.namespaceURI</code> property is
                        <code nobreak="false">"http://www.w3.org/2000/xmlns/"</code>, the attribute is not included in
                        this sequence;</p></item><item><p>If the <code nobreak="false">Attr.localName</code> property is <code nobreak="false">"xmlns"</code>, the attribute
                        is not included in this sequence;</p></item><item><p>If the <code nobreak="false">Attr.localName</code> property starts with <code nobreak="false">"xmlns:"</code>,
                        the attribute is not included in this sequence;</p></item><item><p>Otherwise, the attribute is included in this sequence using the XDM mapping rules
                        described in this section.</p></item></olist><note><p>The HTML DOM <code nobreak="false">Element.attributes</code> property includes namespace and non-namespace
                     attributes in the list when the HTML or XML parser is used. As such, the namespace attributes
                     have to be filtered from the resulting XDM attribute sequence.</p></note><note><p>When the resulting document is an HTML DOM <code nobreak="false">HTMLDocument</code>, the
                     <code nobreak="false">Attr.localName</code> and <code nobreak="false">Attr.name</code> properties of HTML DOM
                     <code nobreak="false">Attr</code> nodes are both set to the qualified name. This includes
                     namespace declarations which are filtered out by the logic in this section.</p></note><note><p>The <code nobreak="false">Attr.localName</code> property will be ASCII lowercase. The
                     <bibref ref="html5"/> section 13.2.5.33, <emph>Attribute name state</emph> specifies that
                     ASCII upper alpha characters are appended to the attribute’s name in lowercase.</p></note></div4><div4 id="html-base-uri-accessor"><head>base-uri Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-base-uri"/>
                  <code nobreak="false">dm:base-uri($node)</code> for an HTML DOM <code nobreak="false">Node</code> is the value of the
                  <code nobreak="false">Node.baseURI</code> property mapped as follows:</p><olist><item><p>If the value is null or the zero-length string, then the result is the empty sequence;</p></item><item><p>Otherwise, the string value is cast to an <code nobreak="false">xs:anyURI</code>.</p></item></olist></div4><div4 id="html-children-accessor"><head>children Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-children"/>
                  <code nobreak="false">dm:children($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Document</code> then the result
                        is the value of the <code nobreak="false">Node.childNodes</code> property mapped to a sequence;</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">HTMLTemplateElement</code> then the
                        result is the HTML DOM <code nobreak="false">DocumentFragment</code>’s <code nobreak="false">Node.childNodes</code>
                              property, mapped to a sequence;</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Element</code> then the result the
                        value of the <code nobreak="false">Node.childNodes</code> property mapped to a sequence;</p></item><item><p>Otherwise, the result is the empty sequence.</p></item></olist><p>An HTML DOM <code nobreak="false">NodeList</code> is mapped to a sequence as follows:</p><olist><item><p><code nobreak="false">NodeList.length</code> is the length of the sequence, where a length
                        of <code nobreak="false">0</code> results in the empty sequence;</p></item><item><p><code nobreak="false">NodeList.item(n)</code> is the n<sup>th</sup> element of the sequence.</p></item></olist><p>That sequence is then filtered as follows:</p><olist><item><p>If the child is an instance of HTML DOM <code nobreak="false">DocumentType</code>, that child
                        is not included in this sequence;</p></item><item><p>A sequence of consecutive HTML DOM <code nobreak="false">Text</code> nodes is combined into a
                        single XDM <code nobreak="false">text</code> node;</p></item><item><p>Otherwise, the HTML DOM <code nobreak="false">Node</code> nodes are mapped to XDM according to
                        the rules in this section.</p></item></olist></div4><div4 id="html-document-uri-accessor"><head>document-uri Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-document-uri"/>
                  <code nobreak="false">dm:document-uri($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Document</code> then the value
                        of the <code nobreak="false">Document.documentURI</code> property mapped as follows:</p><olist><item><p>If the value is null or the zero-length string, then the result is the empty sequence;</p></item><item><p>Otherwise, the string value is cast to an <code nobreak="false">xs:anyURI</code>.</p></item></olist></item><item><p>Otherwise, the result is the empty sequence.</p></item></olist></div4><div4 id="html-is-id-accessor"><head>is-id Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-is-id"/>
                  <code nobreak="false">dm:is-id($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Attr</code> then:</p><olist><item><p>If the <code nobreak="false">Attr.name</code> property (its qualified name) is
                              <code nobreak="false">"id"</code>, then:</p><olist><item><p>If the <code nobreak="false">Attr.value</code> is castable to an <code nobreak="false">xs:NCName</code>,
                                    the result is <code nobreak="false">true</code>;</p></item><item><p>Otherwise, the result is <code nobreak="false">false</code>;</p></item></olist></item><item><p>Otherwise, the result is <code nobreak="false">false</code>;</p></item></olist></item><item><p>Otherwise, the result is <code nobreak="false">false</code>.</p></item></olist><note><p>In <bibref ref="html5"/> section 3.2.5, <emph>Global attributes</emph>, the
                     <code nobreak="false">id</code> attribute is defined as being unique in the element’s tree,
                     containing at least one character, and not having any ASCII whitespace
                     characters. This means that an HTML <code nobreak="false">id</code> attribute may not
                     conform to an <code nobreak="false">xs:NCName</code>.</p><p>If an HTML <code nobreak="false">id</code> is not a valid <code nobreak="false">xs:NCName</code> then that
                     attribute is not an XML ID.</p></note></div4><div4 id="html-is-idrefs-accessor"><head>is-idrefs Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-is-idrefs"/>
                  <code nobreak="false">dm:is-idrefs($node)</code> for an HTML DOM <code nobreak="false">Node</code> is the empty sequence.</p></div4><div4 id="html-namespace-nodes-accessor"><head>namespace-nodes Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-namespace-nodes"/>
                  <code nobreak="false">dm:namespace-nodes($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Element</code> then an
                        <termref def="implementation-dependent">implementation-dependent</termref> sequence
                        of namespace nodes that is sufficient to define the namespace context of the node.</p></item><item><p>Otherwise, the result is the empty sequence.</p></item></olist><p>For the XHTML parsing algorithm, this will be equivalent to constructing the namespace
                  nodes from an XML infoset, PSVI, or similar mapping.</p><p>For the HTML parsing algorithm, the <bibref ref="html5"/> specification defines the
                  namespace context in various places:</p><olist><item><p>Section 2.1.3 <emph>XML compatibility</emph> defines the default element namespace
                        to be <code nobreak="false">http://www.w3.org/1999/xhtml</code>.</p></item><item><p>Section 4.8.15 <emph>MathML</emph> defines rules for embedded MathML content in HTML
                        documents. Section 13.1.2 <emph>Elements</emph> defines these elements as foreign
                        elements, placing them in the MathML namespace (<code nobreak="false">http://www.w3.org/1998/Math/MathML</code>).
                        The default element namespace for these elements is the MathML namespace.</p></item><item><p>Section 4.8.16 <emph>SVG</emph> defines rules for embedded SVG content in HTML
                        documents. Section 13.1.2 <emph>Elements</emph> defines these elements as foreign
                        elements, placing them in the SVG namespace (<code nobreak="false">http://www.w3.org/2000/svg</code>).
                        The default element namespace for these elements is the SVG namespace.</p></item><item><p>Section 13.1.2.3 <emph>Attributes</emph> defines several namespaced attributes
                        available on foreign elements. If any of these namespaced attributes are present,
                        a namespace node for that namespace must be present on the element.</p><p>The supported namespace prefixes are:</p><olist><item><p><code nobreak="false">xlink</code> in the <code nobreak="false">http://www.w3.org/1999/xlink</code> namespace;</p></item><item><p><code nobreak="false">xml</code> in the <code nobreak="false">http://www.w3.org/XML/1998/namespace</code> namespace; and</p></item><item><p><code nobreak="false">xmlns</code> in the <code nobreak="false">http://www.w3.org/2000/xmlns/</code> namespace.</p></item></olist></item></olist><p>No other namespaces are supported by the HTML parser.</p><note><p>Section number references to <bibref ref="html5"/> may change over time.</p></note></div4><div4 id="html-nilled-accessor"><head>nilled Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-nilled"/>
                  <code nobreak="false">dm:nilled($node)</code> for an HTML DOM <code nobreak="false">Node</code> is <code nobreak="false">false()</code>.</p></div4><div4 id="html-node-kind-accessor"><head>node-kind Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-node-kind"/>
                  <code nobreak="false">dm:node-kind($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Document</code> then the result is
                        <code nobreak="false">"document"</code>.</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Element</code> then the result is
                        <code nobreak="false">"element"</code>.</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Attr</code> then the result is
                        <code nobreak="false">"attribute"</code>.</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">ProcessingInstruction</code> then
                        the result is <code nobreak="false">"processing-instruction"</code>.</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Comment</code> then the result is
                        <code nobreak="false">"comment"</code>.</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Text</code> then the result is
                        <code nobreak="false">"text"</code>.</p></item></olist></div4><div4 id="html-node-name-accessor"><head>node-name Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-node-name"/>
                  <code nobreak="false">dm:node-name($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Element</code> then the result is
                        determined as follows:</p><olist><item><p>The <emph>local name</emph> is the value of the
                              <code nobreak="false">Element.localName</code> property. This is derived as follows:</p><olist><item><p>The local name is initially set to the ASCII lowercase tag name. The
                                    <bibref ref="html5"/> section 13.2.5.8, <emph>Tag name state</emph>
                                    specifies that ASCII upper alpha characters are appended to the element’s
                                    name in lowercase.</p></item><item><p>If the local name is an SVG element name, the case-sensitive name is used.
                                    <bibref ref="html5"/> section 13.2.6.5,
                                    <emph>The rules for parsing tokens in foreign content</emph>
                                    has a table mapping the lowercase element names to their SVG names.</p></item><item><p>If the local name contains a character that is not a valid XML
                                    <code nobreak="false">NameStartChar</code> or <code nobreak="false">NameChar</code>, then an
                                    <termref def="implementation-defined">implementation-defined</termref>
                                    replacement string is used. The result must be a valid <code nobreak="false">NCName</code>.</p><note><p><bibref ref="html5"/> section 13.2.9
                                       <emph>Coercing an HTML DOM into an infoset</emph> uses a
                                       <code nobreak="false">Unnnnnn</code> escape sequence. That would map <code nobreak="false">:</code>
                                       to <code nobreak="false">U00003A</code>.</p><p>This local name escaping applies only to the HTML parsing algorithm.
                                       If the XHTML parsing algorithm is used, the <code nobreak="false">localName</code> and
                                       <code nobreak="false">prefix</code> will be correctly set for QName-based
                                       node names.</p></note></item></olist></item><item><p>The <emph>namespace prefix</emph> is the value of the
                              <code nobreak="false">Element.prefix</code> property, or empty if the value is null;</p></item><item><p>The <emph>namespace URI</emph> is the value of the
                              <code nobreak="false">Element.namespaceURI</code> property, or empty if the value
                              is null.</p><olist><item><p>If the element is an HTML element, the namespace URI is
                                    <code nobreak="false">"http://www.w3.org/1999/xhtml"</code>.</p></item><item><p>If the element is an SVG element, the namespace URI is
                                    <code nobreak="false">"http://www.w3.org/2000/svg"</code>.</p></item><item><p>If the element is a MathML element, the namespace URI is
                                    <code nobreak="false">"http://www.w3.org/1998/Math/MathML"</code>.</p></item></olist></item></olist></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Attr</code> then the result is
                        determined as follows:</p><olist><item><p>The <emph>attribute name</emph> is the tokenized attribute name. The
                              <bibref ref="html5"/> section 13.2.5.33, <emph>Attribute name state</emph>
                              specifies that ASCII upper alpha characters are appended to the attribute’s
                              name in lowercase.</p></item><item><p>The <emph>local name</emph> is the value of the
                              <code nobreak="false">Attr.localName</code> property. This is derived as follows:</p><olist><item><p>The local name is initially set to the <emph>attribute name</emph>.</p></item><item><p>If the local name is an SVG or MathML attribute name, the case-sensitive name
                                    is used. <bibref ref="html5"/> section 13.2.6.1,
                                    <emph>Creating and inserting nodes</emph>
                                    has a table mapping the lowercase attribute names to their SVG/MathML names.</p></item><item><p>If the local name is an allowed <code nobreak="false">xlink</code>, <code nobreak="false">xml</code>, or
                                    <code nobreak="false">xmlns</code> attribute name the local name is the value of the local name
                                    column of the attribute name mapping table in <bibref ref="html5"/> section
                                    13.2.6.1, <emph>Creating and inserting nodes</emph>.</p></item><item><p>If the local name contains a character that is not a valid XML
                                    <code nobreak="false">NameStartChar</code> or <code nobreak="false">NameChar</code>, then an
                                    <termref def="implementation-defined">implementation-defined</termref>
                                    replacement string is used. The result must be a valid <code nobreak="false">NCName</code>.</p><note><p><bibref ref="dom-ls"/> section 13.2.9
                                       <emph>Coercing an HTML DOM into an infoset</emph> uses a
                                       <code nobreak="false">Unnnnnn</code> escape sequence. That would map <code nobreak="false">:</code>
                                       to <code nobreak="false">U00003A</code>.</p><p>This local name escaping applies only to the HTML parsing algorithm.
                                       If the XHTML parsing algorithm is used, the <code nobreak="false">localName</code> and
                                       <code nobreak="false">prefix</code> will be correctly set for QName-based
                                       node names.</p></note></item></olist></item><item><p>The <emph>namespace prefix</emph> is the value of the
                              <code nobreak="false">Attr.prefix</code> property, or empty if the value is null.</p><olist><item><p>If the attribute name is an allowed <code nobreak="false">xlink</code>, <code nobreak="false">xml</code>, or
                                    <code nobreak="false">xmlns</code> attribute name the namespace prefix is the value of the
                                    prefix column of the attribute name mapping table in <bibref ref="html5"/>
                                    section 13.2.6.1, <emph>Creating and inserting nodes</emph>.</p></item></olist></item><item><p>The <emph>namespace URI</emph> is the value of the
                              <code nobreak="false">Attr.namespaceURI</code> property, or empty if the value is null;</p><olist><item><p>If the attribute name is an allowed <code nobreak="false">xlink</code>, <code nobreak="false">xml</code>, or
                                    <code nobreak="false">xmlns</code> attribute name the namespace URI is the value of the
                                    namespace column of the attribute name mapping table in <bibref ref="html5"/>
                                    section 13.2.6.1, <emph>Creating and inserting nodes</emph>.</p></item></olist></item></olist></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">ProcessingInstruction</code> then
                        the result is an <code nobreak="false">xs:QName</code> constructed as follows:</p><olist><item><p>The <emph>local name</emph> is the value of the
                              <code nobreak="false">ProcessingInstruction.target</code> property;</p></item><item><p>The <emph>namespace prefix</emph> is empty;</p></item><item><p>The <emph>namespace URI</emph> is empty;</p></item></olist></item><item><p>Otherwise, the result is the empty sequence.</p></item></olist><note><p>When the resulting document is an HTML DOM <code nobreak="false">HTMLDocument</code>, the
                     <code nobreak="false">Element.localName</code> and <code nobreak="false">Element.name</code> properties of
                     HTML DOM <code nobreak="false">Element</code> nodes are both set to the qualified name.</p></note><note><p>When the resulting document is an HTML DOM <code nobreak="false">HTMLDocument</code>, the
                     <code nobreak="false">Attr.localName</code> and <code nobreak="false">Attr.name</code> properties of HTML DOM
                     <code nobreak="false">Attr</code> nodes are both set to the qualified name.</p></note></div4><div4 id="html-parent-accessor"><head>parent Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-parent"/>
                  <code nobreak="false">dm:parent($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>Let <code nobreak="false">$parent</code> be the <code nobreak="false">Node.parentNode</code> property of the
                        node;</p></item><item><p>If <code nobreak="false">$parent</code> is an instance of HTML DOM <code nobreak="false">DocumentFragment</code>,
                        then for each HTML DOM <code nobreak="false">HTMLTemplateElement</code> <code nobreak="false">$template</code> in
                        the parsed DOM tree:</p><olist><item><p>Let <code nobreak="false">$content</code> be the value of the
                              <code nobreak="false">HTMLTemplateElement.content</code> property of <code nobreak="false">$template</code>;</p></item><item><p>If <code nobreak="false">$content</code> is the same node as <code nobreak="false">$parent</code>, then the
                              result is <code nobreak="false">$template</code> using the XDM mapping rules described in
                              this section;</p></item><item><p>If there are no more <code nobreak="false">$template</code> nodes, then the result is an
                              empty sequence;</p></item></olist></item><item><p>If <code nobreak="false">$parent</code> is null, then the result is the empty sequence;</p></item><item><p>Otherwise, the result is <code nobreak="false">$parent</code> using the XDM mapping rules
                        described in this section.</p></item></olist><note><p>The current node can have a HTML DOM <code nobreak="false">DocumentFragment</code> parent node only
                     if the <code nobreak="false">include-template-content</code> key of the <code nobreak="false">html-parser-options</code>
                     is <code nobreak="false">true()</code>.</p></note><note><p>The HTML DOM <code nobreak="false">DocumentFragment</code>’s <code nobreak="false">Node.parentNode</code> property
                     is null, and a <code nobreak="false">DocumentFragment</code> attached to <code nobreak="false">HTMLTemplateElement.content</code>
                     property does not have a <code nobreak="false">host</code> property connecting the fragment back to
                     the template element.</p><p>If a future version of <bibref ref="dom-ls"/> adds a <code nobreak="false">DocumentFragment.host</code>
                     property that references the node’s <code nobreak="false">template</code> element, or the implementation
                     has access to that internal property, the implementation may choose to use that
                     instead of traversing the parsed HTML tree.</p></note></div4><div4 id="html-string-value-accessor"><head>string-value Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-string-value"/>
                  <code nobreak="false">dm:string-value($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Document</code>, then use the
                        algorithm described in <specref ref="html-tree-string-construction"/>;</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Element</code>, then use the
                        algorithm described in <specref ref="html-tree-string-construction"/>;</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Text</code>, then use the
                        algorithm described in <specref ref="html-text-node-string-construction"/>;</p></item><item><p>Otherwise, the result is the value of the <code nobreak="false">Node.nodeValue</code> property.</p></item></olist><div5 id="html-tree-string-construction"><head>Tree string construction</head><p>The following algorithm is used to construct the concatenated string value of a
                     node in the HTML DOM tree:</p><olist><item><p>Let <code nobreak="false">$text</code> be the string value <code nobreak="false">""</code>;</p></item><item><p>For each descendant node <code nobreak="false">$node</code> in document order:</p><olist><item><p>If <code nobreak="false">$node</code> is not an instance of HTML DOM
                                 <code nobreak="false">Text</code>, process the next node in document order;</p></item><item><p>Append the value of the <code nobreak="false">Node.nodeValue</code> property for
                                 <code nobreak="false">$node</code> to <code nobreak="false">$text</code>;</p></item></olist></item><item><p>The result is <code nobreak="false">$text</code>.</p></item></olist></div5><div5 id="html-text-node-string-construction"><head>Text node string construction</head><p>The following algorithm is used to construct the maximal sequence of adjacent
                     <emph>character information items</emph> for text node children of an element:</p><olist><item><p>Let <code nobreak="false">$text</code> be the string value <code nobreak="false">""</code>;</p></item><item><p>Append the value of the <code nobreak="false">Node.nodeValue</code> property for
                           <code nobreak="false">$node</code> to <code nobreak="false">$text</code>;</p></item><item><p>Let <code nobreak="false">$next</code> be the value of <code nobreak="false">Node.nextSibling</code>;</p></item><item><p>Let <code nobreak="false">$next</code> is null, or not an instance of HTML DOM
                           <code nobreak="false">Text</code>, the result is <code nobreak="false">$text</code>;</p></item><item><p>Otherwise, repeat from step 2 using <code nobreak="false">$next</code> as <code nobreak="false">$node</code>.</p></item></olist><note><p>Adjacent text nodes in the HTML DOM are treated as a single XDM text node by only
                        including the first text node and providing logic to ensure that the text content
                        is merged into a single text block.</p></note></div5></div4><div4 id="html-type-name-accessor"><head>type-name Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-type-name"/>
                  <code nobreak="false">dm:type-name($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>If the node is an instance of HTML DOM <code nobreak="false">Element</code> then the result is
                        <code nobreak="false">xs:untyped</code>.</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Attr</code> then the result is
                        <code nobreak="false">xs:untypedAtomic</code>.</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Text</code> then the result is
                        <code nobreak="false">xs:untypedAtomic</code>.</p></item><item><p>Otherwise, the result is the empty sequence.</p></item></olist></div4><div4 id="html-typed-value-accessor"><head>typed-value Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-typed-value"/>
                  <code nobreak="false">dm:typed-value($node)</code> for an HTML DOM <code nobreak="false">Node</code> is as follows:</p><olist><item><p>Let <code nobreak="false">$string-value</code> be the <specref ref="html-string-value-accessor"/>
                        for the node;</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Document</code> then the result is
                        <code nobreak="false">$string-value</code> as an <code nobreak="false">xs:untypedAtomic</code>;</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Element</code> then the result is
                        <code nobreak="false">$string-value</code> as an <code nobreak="false">xs:untypedAtomic</code>;</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Attr</code> then the result is
                        <code nobreak="false">$string-value</code> as an <code nobreak="false">xs:untypedAtomic</code>;</p></item><item><p>If the node is an instance of HTML DOM <code nobreak="false">Text</code> then the result is
                        <code nobreak="false">$string-value</code> as an <code nobreak="false">xs:untypedAtomic</code>;</p></item><item><p>Otherwise, the result is <code nobreak="false">$string-value</code>.</p></item></olist></div4><div4 id="html-unparsed-entity-public-id-accessor"><head>unparsed-entity-public-id Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-unparsed-entity-public-id"/>
                  <code nobreak="false">dm:unparsed-entity-public-id($node)</code> for an HTML DOM <code nobreak="false">Node</code>
                  is the empty sequence.</p></div4><div4 id="html-unparsed-entity-system-id-accessor"><head>unparsed-entity-system-id Accessor</head><p>The result of the <xspecref spec="DM40" ref="dm-unparsed-entity-system-id"/>
                  <code nobreak="false">dm:unparsed-entity-system-id($node)</code> for an HTML DOM <code nobreak="false">Node</code>
                  is the empty sequence.</p></div4></div3><div3 id="func-parse-html"><head>fn:parse-html</head><changes><change issue="74 850 1799 1889 1891 2210" PR="259 956" date="2023-01-10">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>This function takes as input an HTML document, and returns the
            document node at the root of an XDM tree representing the parsed document.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-html" return-type="document-node(*:html)?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="(xs:string | xs:hexBinary | xs:base64Binary)?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>In other cases, <code nobreak="false">$value</code> is expected to contain an HTML document supplied
         either as a string or a binary value.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="encoding" type="xs:string" occur="opt"/><arg name="fail-on-error" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">encoding?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">
                  <p>The character encoding to use to decode a sequence of octets that
                  represents an HTML document. Note that encoding names are case-insensitive.</p>
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">fail-on-error?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">
                  <p>Indicates whether the function should fail with a dynamic error if the input
                     is not syntactically valid.</p>
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">
                     Parsing errors should be handled as described in 
                     <bibref ref="html5"/> section 13.2.2, <emph>Parse Errors</emph>.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">
                     A parsing error should result in the function failing with a dynamic error.
                  </td></tr></tbody></table><p>The <termref def="option-parameter-conventions"/> apply.</p><p>If <code nobreak="false">$value</code> is not the empty sequence, an input byte stream is constructed as follows:</p><olist><item><p>If <code nobreak="false">$value</code> is an <code nobreak="false">xs:string</code>, then in principle no decoding is needed.
                  Conceptually, however, the HTML parsing algorithm always starts by decoding an octet
                  stream. The string is therefore first encoded using UTF-8, and the resulting octet
                  stream is then passed to the HTML parser with a <term>known definite encoding</term>
                  of UTF-8, as described in <bibref ref="html5"/> section 13.2.3.1,
                  <emph>Parsing with a known character encoding</emph>.</p><p>If the first codepoint of the string is <char>U+FEFF</char>, this should be stripped, since
               it might otherwise lead to an incorrect encoding inference.</p></item><item><p>If the type of <code nobreak="false">$value</code> is a sequence of octets (<code nobreak="false">xs:hexBinary</code> or
                  <code nobreak="false">xs:base64Binary</code>) the encoding of the input byte stream is determined in a
                  way consistent with <bibref ref="html5"/> section 13.2.3.2, <emph>Determining the character
                  encoding</emph>:</p><olist><item><p>The <code nobreak="false">encoding</code> key of <code nobreak="false">$options</code> is interpreted in step 2 of
                        <emph>Determining the character encoding</emph> as the user instructing the user
                        agent to override the document’s character encoding with the specified encoding.</p></item><item><p>If the <code nobreak="false">encoding</code> key of <code nobreak="false">$options</code> is not specified, step 2
                        of <emph>Determining the character encoding</emph> is skipped.</p></item></olist></item></olist><olist><item><p>Tokenizing the byte stream according to the HTML parsing algorithm as described in
                  <bibref ref="html5"/> section 13.2.5, <emph>Tokenization</emph>.</p></item><item><p>Constructing a <code nobreak="false">HTMLDocument</code> object for HTML documents, or an
                  <code nobreak="false">XMLDocument</code> for XML/XHTML documents as described in 
                  <bibref ref="html5"/> section 13.2.6, <emph>Tree construction</emph>.</p></item><item><p>Building an XDM representation of the <code nobreak="false">HTMLDocument</code> or <code nobreak="false">XMLDocument</code>
                  according to the rules in <specref ref="html-xdm-mapping"/>.</p></item></olist><p>The implementation <rfc2119>should</rfc2119> process any input HTML that adheres to the current
         practice of mainstream web browsers, as this evolves over time. Since this is defined
         by a “living standard” (see <bibref ref="html5"/>), no specific version is prescribed. 
         An implementation <rfc2119>may</rfc2119>
         define additional options to control aspects of the HTML parsing algorithm, including the selection
         of a specific HTML parsing library; it may also provide options to process alternative HTML versions
         or dialects.</p><p>The implementation <rfc2119>should</rfc2119> recognize and process XHTML (referred to
            in <bibref ref="html5"/> as the XML concrete syntax of HTML).</p><p>The function is <termref def="dt-nondeterministic">nondeterministic with respect to node identity</termref>:
            that is, if the function is called twice with the same arguments, it is
            <termref def="implementation-dependent"/> whether the same node is returned on both
            occasions.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="DC" code="0011"/> if the content of
            <code nobreak="false">$value</code> is not a well-formed HTML document. This includes the case
            where <code nobreak="false">$value</code> cannot be decoded using the specified encoding.</p></def></gitem><gitem><label>Notes</label><def><note><p>If the HTML parser accepts a string as the input then that may be used directly when
            <code nobreak="false">$value</code> is an <code nobreak="false">xs:string</code> instead of converting the string to
            a sequence of octets in an <termref def="implementation-dependent"/> encoding. The HTML
            parser must not perform character encoding processing on that input, treating the HTML
            string as being in a known character encoding that matches the encoding of the string.</p><p>The WHATWG Encoding specification defines the ISO 8859-1 (latin1) and ASCII encodings as
            aliases of the windows-1252 encoding.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>The expression <code nobreak="false">parse-html(())</code> returns <code nobreak="false">()</code>.</p></td></tr><tr><td colspan="2" rowspan="1"><p>The expression <code nobreak="false">parse-html("&lt;p&gt;Hello&lt;/p&gt;")</code> returns an XDM

               document node equivalent to the result of parsing the XML 
               <code nobreak="false">&lt;html xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Hello&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</code></p></td></tr><tr><td colspan="2" rowspan="1"><p>The expression <code nobreak="false">parse-html("&lt;p&gt;Hi&lt;/p&gt;", method:="html")</code>
               is equivalent to <code nobreak="false">parse-html("&lt;p&gt;Hi&lt;/p&gt;")</code>.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-html-doc"><head>fn:html-doc</head><changes><change issue="748" PR="2013" date="2025-05-20">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Reads an external resource containing HTML, and returns the result of parsing the resource as HTML.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="html-doc" return-type="document-node(*:html)?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The effect of the two-argument function call <code nobreak="false">fn:html-doc($H, $M)</code>is equivalent to the function composition
            <code nobreak="false">fn:unparsed-binary($H) =&gt; fn:parse-html($M)</code>.</p><p>If <code nobreak="false">$source</code> is the empty sequence, the function returns the empty sequence.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note></def></gitem><gitem><label>Error Conditions</label><def><p>The function may raise any error defined for the <function>fn:unparsed-binary</function>
         or <function>fn:parse-html</function> functions.</p></def></gitem></glist></div3></div2><div2 id="json-functions"><head>Functions on JSON Data</head><p>The functions listed in this section parse or serialize JSON data.</p><p>JSON is a popular format for exchange of structured data on the web: it is specified in <bibref ref="rfc7159"/>.
               This section describes facilities
               allowing JSON data to be converted to and from XDM values.</p><p>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.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-json</code></td><td rowspan="1" colspan="1">Parses input supplied in the form of a JSON text, returning the results typically in the form
            of a map or array.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:json-doc</code></td><td rowspan="1" colspan="1">Reads an external resource containing JSON, and returns the result of parsing the resource as JSON.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:json-to-xml</code></td><td rowspan="1" colspan="1">Parses a string supplied in the form of a JSON text, returning the results in the form
            of an XML <phrase>document node</phrase>.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:xml-to-json</code></td><td rowspan="1" colspan="1">Converts an XML tree, whose format corresponds to the XML representation of JSON defined
            in this specification, into a string conforming to the JSON grammar.</td></tr></tbody></table><p>Note also:</p><ulist><item><p>The function <function>fn:serialize</function> has an option to generate
                  JSON output from a structure of maps and arrays.</p></item><item><p>The function <function>fn:element-to-map</function> enables
                  arbitrary XML node trees to be converted to trees of maps and arrays
                  suitable for serializing as JSON.</p></item></ulist><div3 id="json-to-maps-and-arrays"><head>Representing JSON using maps and arrays</head><p>This section defines a mapping from JSON data to XDM maps and arrays. Two functions are available
                     to support this mapping: <function>fn:parse-json</function> and <function>fn:serialize</function> (with options
                     selecting JSON as the output method).
                     The <function>fn:parse-json</function> function will accept any JSON text as input, and converts it
                     to XDM data values. The <function>fn:serialize</function> function (with JSON as the output method) will accept any XDM
                     value produced using <function>fn:parse-json</function> and convert it back to the original JSON text
                     (subject to insignificant variations such as reordering the properties in a JSON object). </p><note><p>The conversion is lossless if recommended JSON good practice is followed. Information may however be lost if
                     (a) JSON numbers are not exactly representable as double-precision floating point, or (b) duplicate key
                     values appear within a JSON object.</p></note><p>The representation of JSON data produced by the <function>fn:parse-json</function> function
                     has been chosen with ease of manipulation as a design aim. For example, a simple JSON object
                     such as <code nobreak="false">{ "Sun": 1, "Mon": 2, "Tue": 3, ... }</code> produces a simple map, so if the result
                     of parsing is held in <code nobreak="false">$weekdays</code>, the number for a given weekday can be extracted
                     using an expression such as <code nobreak="false">$weekdays?Tue</code>. Similarly, a simple array such as
                     <code nobreak="false">[ "Sun", "Mon", "Tue", ... ]</code> produces an array that can be addressed as, for example,
                     <code nobreak="false">$weekdays(3)</code>. A more deeply nested structure can be addressed in a similar way:
                     for example if the JSON text is an array of person objects, each of which has a property named
                     <code nobreak="false">phones</code> which is an array of strings containing phone numbers, then the first phone number of
                     each person in the data can be addressed as <code nobreak="false">$data?phones(1)</code>.</p></div3><div3 id="json-to-xml-mapping"><head>XML Representation of JSON</head><p>This section defines a mapping from JSON data to XML (specifically, to XDM element and attribute nodes). A
                     function <function>fn:json-to-xml</function> is provided to take a JSON string as input and convert it
                     to the XML representation, and a second function <function>fn:xml-to-json</function> performs the reverse operation.</p><p>The XML representation is designed to be capable of representing any valid JSON text including
                     one that uses characters which are not valid in XML. The transformation is normally lossless: that is,
                     distinct JSON texts convert to distinct XML representations. When converting JSON to XML, options are provided
                     to reject unsupported characters, to replace them with a substitute character, or to leave them in
                     backslash-escaped form.</p><note><p>The conversion is lossless if recommended JSON good practice is followed. Information may however be lost if
                     (a) JSON numbers are not exactly representable as double-precision floating point, or (b) duplicate key
                     values appear within a JSON object.</p></note><p>The following example demonstrates the correspondence of a JSON text and the corresponding XML
                     representation. </p><example><head>A JSON Text and its XML Representation</head><p>Consider the following JSON text:</p><eg xml:space="preserve">
{
  "desc"    : "Distances between several cities, in kilometers.",
  "updated" : "2014-02-04T18:50:45",
  "uptodate": true,
  "author"  : null,
  "cities"  : {
    "Brussels": [
      { "to": "London",    "distance": 322 },
      { "to": "Paris",     "distance": 265 },
      { "to": "Amsterdam", "distance": 173 }
    ],
    "London": [
      { "to": "Brussels",  "distance": 322 },
      { "to": "Paris",     "distance": 344 },
      { "to": "Amsterdam", "distance": 358 }
    ],
    "Paris": [
      { "to": "Brussels",  "distance": 265 },
      { "to": "London",    "distance": 344 },
      { "to": "Amsterdam", "distance": 431 }
    ],
    "Amsterdam": [
      { "to": "Brussels",  "distance": 173 },
      { "to": "London",    "distance": 358 },
      { "to": "Paris",     "distance": 431 }
    ]
  }
}</eg><p>The XML representation of this text is as follows. Whitespace is included in the XML representation for purposes of illustration,
                        but it will not necessarily be present in the output of the
                        <function>json-to-xml</function> function.</p><eg xml:space="preserve">
&lt;map xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;string key="desc"&gt;Distances between several cities, in kilometers.&lt;/string&gt;
  &lt;string key="updated"&gt;2014-02-04T18:50:45&lt;/string&gt;
  &lt;boolean key="uptodate"&gt;true&lt;/boolean&gt;
  &lt;null key="author"/&gt;
  &lt;map key="cities"&gt;
    &lt;array key="Brussels"&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;London&lt;/string&gt;
        &lt;number key="distance"&gt;322&lt;/number&gt;
      &lt;/map&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Paris&lt;/string&gt;
        &lt;number key="distance"&gt;265&lt;/number&gt;
      &lt;/map&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Amsterdam&lt;/string&gt;
        &lt;number key="distance"&gt;173&lt;/number&gt;
      &lt;/map&gt;
    &lt;/array&gt;
    &lt;array key="London"&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Brussels&lt;/string&gt;
        &lt;number key="distance"&gt;322&lt;/number&gt;
      &lt;/map&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Paris&lt;/string&gt;
        &lt;number key="distance"&gt;344&lt;/number&gt;
      &lt;/map&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Amsterdam&lt;/string&gt;
        &lt;number key="distance"&gt;358&lt;/number&gt;
      &lt;/map&gt;
    &lt;/array&gt;
    &lt;array key="Paris"&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Brussels&lt;/string&gt;
        &lt;number key="distance"&gt;265&lt;/number&gt;
      &lt;/map&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;London&lt;/string&gt;
        &lt;number key="distance"&gt;344&lt;/number&gt;
      &lt;/map&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Amsterdam&lt;/string&gt;
        &lt;number key="distance"&gt;431&lt;/number&gt;
      &lt;/map&gt;
    &lt;/array&gt;
    &lt;array key="Amsterdam"&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Brussels&lt;/string&gt;
        &lt;number key="distance"&gt;173&lt;/number&gt;
      &lt;/map&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;London&lt;/string&gt;
        &lt;number key="distance"&gt;358&lt;/number&gt;
      &lt;/map&gt;
      &lt;map&gt;
        &lt;string key="to"&gt;Paris&lt;/string&gt;
        &lt;number key="distance"&gt;431&lt;/number&gt;
      &lt;/map&gt;
    &lt;/array&gt;
  &lt;/map&gt;
&lt;/map&gt;</eg></example><p>An XSD 1.0 schema for the XML representation is provided in <specref ref="schema-for-json"/>.
                     It is not necessary to import this schema into the static context unless the stylesheet or query
                     makes explicit reference to the components defined in the schema. If the stylesheet or query does import a schema
                     for the namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>, then:</p><olist><item><p>Unless the host language specifies otherwise, the processor (if it is schema-aware)
                        <rfc2119>must</rfc2119> recognize an import declaration for
                        this namespace, whether or not a schema location is supplied.</p></item><item><p>If a schema location is provided, then the schema document at that location <rfc2119>must</rfc2119>
                        be equivalent to the schema document at <specref ref="schema-for-json"/>; the effect if it is not equivalent is
                        <termref def="implementation-dependent"/></p></item></olist><p>The rules governing the mapping from JSON to XML are as follows. In these rules, the phrase
                     “an element named N” is to be interpreted as meaning “an element node whose local name is N and whose
                     namespace URI is <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>”.</p><olist><item><p>The JSON value <code nobreak="false">null</code> is represented by an element named <code nobreak="false">null</code>, with empty content.</p></item><item><p>The JSON values <code nobreak="false">true</code> and <code nobreak="false">false</code> are represented by an element named <code nobreak="false">boolean</code>,
                        with content conforming to the type <code nobreak="false">xs:boolean</code>. When the element is created by the
                        <function>fn:json-to-xml</function> function, the string value of the element will be <code nobreak="false">true</code> or <code nobreak="false">false</code>.
                        The <function>fn:xml-to-json</function> function also recognizes other strings that validate as <code nobreak="false">xs:boolean</code>,
                        for example <code nobreak="false">1</code> and <code nobreak="false">0</code>. Leading and trailing whitespace is accepted.
                     </p></item><item><p>A JSON number is represented by an element named <code nobreak="false">number</code>,
                        with content conforming to the type <code nobreak="false">xs:double</code>, with the additional restriction that the value
                        must not be positive or negative infinity, nor <code nobreak="false">NaN</code>. The
                        <function>fn:json-to-xml</function> function creates an element whose string value is lexically the same as the JSON representation
                        of the number. The <function>fn:xml-to-json</function> function generates a JSON representation that is the result of casting the
                        (typed or untyped) value of the node to <code nobreak="false">xs:double</code> and then casting the result to <code nobreak="false">xs:string</code>.
                        Leading and trailing whitespace is accepted.
                        Since JSON does not impose limits on the range or precision
                        of numbers, these rules mean that conversion from JSON to XML will always succeed, and will retain full precision
                        in the lexical representation unless the data model implementation is one that reconstructs the string value from
                        the typed value. In the reverse direction, conversion from XML to JSON may fail if the value is infinity or <code nobreak="false">NaN</code>,
                        or if the string value is such that casting to <code nobreak="false">xs:double</code> produces positive or negative infinity.
                     </p></item><item><p>A JSON string is represented by an element named <code nobreak="false">string</code>, with
                        content conforming to the type <code nobreak="false">xs:string</code>. The <code nobreak="false">string</code> element has two
                        alternative representations: escaped form, and unescaped form.</p></item><item><p>A JSON array is represented by an element named <code nobreak="false">array</code>. The content is a sequence of
                        child elements representing the members of the array in order, each such element being the representation
                        of the array member obtained by applying these rules recursively.</p></item><item><p>A JSON object is represented by an element named <code nobreak="false">map</code>. The content is a sequence
                        of child elements each of which represents one of the name/value pairs in the object. The representation of the
                        name/value pair <var>N:V</var> is obtained by taking the element that represents the value <var>V</var> (by applying these
                        rules recursively) and adding an attribute with name <code nobreak="false">key</code> (in no namespace), whose
                        value is <var>N</var> as an instance of <code nobreak="false">xs:string</code>. The functions <function>fn:json-to-xml</function> and
                        <function>fn:xml-to-json</function> both retain the order of entries, subject to rules about how duplicate keys are handled. The
                        key may be represented in escaped or unescaped form.</p></item></olist><p>The attribute <code nobreak="false">escaped="true"</code> may be specified on a <code nobreak="false">string</code> element to indicate
                     that the string value contains backslash-escaped characters that are to be interpreted according to the JSON
                     rules. The attribute <code nobreak="false">escaped-key="true"</code> may be specified on any element with a <code nobreak="false">key</code> attribute to indicate
                     that the key contains backslash-escaped characters that are to be interpreted according to the JSON
                     rules. Both attributes have the default value <code nobreak="false">false</code>, signifying that the relevant value is in unescaped form.
                     In unescaped form, the backslash character has no special significance (it represents itself).</p><p>The JSON grammar for <code nobreak="false">number</code> is a subset of the lexical space of
                     the XSD type <code nobreak="false">xs:double</code>. The mapping from JSON <code nobreak="false">number</code> values to <code nobreak="false">xs:double</code>
                     values is defined by the XPath rules for casting from <code nobreak="false">xs:string</code> to <code nobreak="false">xs:double</code>. Note that
                     these rules will never generate an error for out-of-range values; instead very large or very small values will be
                     converted to <code nobreak="false">+INF</code> or <code nobreak="false">-INF</code>. Since JSON does not impose limits on the range or precision
                     of numbers, the conversion is not guaranteed to retain full precision.</p><p>Although the order of entries in a JSON object is generally considered to have no significance, the functions
                     <code nobreak="false">json-to-xml</code> and <code nobreak="false">xml-to-json</code> both retain order.</p><p>The XDM representation of a JSON value may either be untyped (all elements annotated as <code nobreak="false">xs:untyped</code>, attributes
                     as <code nobreak="false">xs:untypedAtomic</code>), or it may be typed. If it is typed, then it <rfc2119>must</rfc2119> have the type
                     annotations obtained by validating the untyped representation against the schema given in <specref ref="schema-for-json"/>.
                     If it is untyped, then it <rfc2119>must</rfc2119> be an XDM instance such that validation against this schema would succeed;
                     with the proviso that all attributes other than those in no namespace or in namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>
                     are ignored, including attributes such as <code nobreak="false">xsi:type</code> and <code nobreak="false">xsi:nil</code> that would normally influence the process
                     of schema validation.</p><p>The namespace prefix associated with the namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code> (if any) is immaterial.
                     The effect of the <function>fn:xml-to-json</function> function does not depend on the choice of prefix, and the prefix (if any) generated by the
                     <function>fn:json-to-xml</function> function is <termref def="implementation-dependent">implementation-dependent</termref>.</p></div3><div3 id="json-character-repertoire"><head>JSON character repertoire</head><changes><change issue="414" PR="546" date="2023-07-25">
                     The rules regarding use of non-XML characters in JSON texts have been relaxed.
                  </change></changes><p>The set of characters that may appear in JSON texts is not the same as
               the set of characters allowed in XML. Specifically:</p><ulist><item><p>As plain unescaped characters, JSON allows any codepoint in the
                  numeric range 0x20 to 0x10FFFF, with the exception of <char>U+0022</char>
                  and <char>U+005C</char>.</p></item><item><p>As a backslash-escaped character, JSON allows any codepoint in the
                  numeric range 0x00 to 0xFFFF.</p></item><item><p>Whether escaped or not, the JSON grammar allows codepoints in the surrogate
                  range to appear, and does not explicitly require that they be properly paired.
                  However, the JSON specifications recognize that unpaired surrogates are likely to lead
                  to interoperability problems.</p></item></ulist><p>Ignoring unpaired surrogates, this means that JSON allows codepoints that are not
                  allowed by XML:</p><ulist><item><p>Not allowed by XML 1.0: 0x00 to 0x1F (other than 0x09, 0x0A, and 0x0D); 0xFFFE; 0xFFFF.</p></item><item><p>Not allowed by XML 1.1: 0x00; 0xFFFE; 0xFFFF.</p></item></ulist><p>The XDM data model (see <xspecref spec="DM40" ref="xml-and-xsd-versions"/>) allows
               an implementation to define the set of <termref def="dt-permitted-character">permitted characters</termref>
               in the <code nobreak="false">xs:string</code> data type in such a way that any
               Unicode codepoint assigned to a character (which excludes surrogates) 
               is allowed. However, this
               is not required: a conformant implementation <rfc2119>may</rfc2119> restrict the set of
               codepoints to those permitted by XML 1.0 or XML 1.1.</p><p>In consequence, parsing of conformant JSON texts may fail if they contain codepoints
               that the implementation does not support. However, if such codepoints are represented
               in the input using JSON escape sequences, these specifications define 
               mechanisms for dealing with them, for example by substituting a replacement character.</p></div3><div3 id="func-parse-json"><head>fn:parse-json</head><changes><change issue="414" PR="546" date="2023-07-25">The rules regarding use of non-XML characters in JSON texts have been relaxed.</change><change issue="960" PR="1028" date="2024-02-20">An option is provided to control how the JSON <code nobreak="false">null</code> value should be handled.</change><change issue="973 1037" PR="975 1058 1246" date="2024-03-12">An option is provided to control how JSON numbers should be formatted.</change><change issue="641" PR="2387" date="2026-01-16">It is now recommended that out-of-range <code nobreak="false">xs:double</code> values should translate
               to positive or negative infinity.</change><change issue="1555" PR="1565" date="2024-11-11">The default for the <code nobreak="false">escape</code> option has been changed to <code nobreak="false">false</code>. The 3.1
            specification gave the default value as <code nobreak="false">true</code>, 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.</change><change issue="1651" PR="1703" date="2025-01-14">The order of entries in maps is retained.</change></changes><glist><gitem><label>Summary</label><def><p>Parses input supplied in the form of a JSON text, returning the results typically in the form
            of a map or array.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-json" return-type="item()?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The first argument is a JSON text as defined in <bibref ref="rfc7159"/>, in the form of a string or binary value. The function
            parses this input to return an XDM value.</p><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><note><p>If the input is <code nobreak="false">"null"</code>, the result will also be the empty sequence.</p></note><p>The <code nobreak="false">$options</code> argument can be used to control the way in which the parsing
            takes place. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="liberal" type="xs:boolean" occur="opt"/><arg name="duplicates" type="xs:string" occur="opt"/><arg name="escape" type="xs:boolean" occur="opt"/><arg name="fallback" type="(fn(xs:string) as xs:anyAtomicType)?" occur="opt"/><arg name="null" type="item()*" occur="opt"/><arg name="number-parser" type="(fn(xs:untypedAtomic) as item()?)?" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="3" colspan="1"><p><code nobreak="false">liberal?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether deviations from the syntax of RFC7159 are permitted.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">
                     The input <rfc2119>must</rfc2119> consist of <phrase>an optional byte order mark (which is ignored) followed by</phrase> a string
                     that conforms to the grammar of <code nobreak="false">JSON-text</code> in <bibref ref="rfc7159"/>. An error <rfc2119>must</rfc2119> be raised
                     <errorref class="JS" code="0001"/> if the input does not conform to the grammar.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">
                     The input <rfc2119>may</rfc2119> contain deviations from the grammar of <bibref ref="rfc7159"/>,
                     which are handled in an <termref def="implementation-defined">implementation-defined</termref> 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 <rfc2119>may</rfc2119> be raised
                     <errorref class="JS" code="0001"/> if the input does not conform to the grammar.
                  </td></tr><tr><td rowspan="4" colspan="1"><p><code nobreak="false">duplicates?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">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 <phrase><code nobreak="false">escape</code> option is set to <code nobreak="false">true</code></phrase>, in which
                  case keys are compared in escaped form. 
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">use-first</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">reject</code></td><td rowspan="1" colspan="1">
                     An error is raised <errorref class="JS" code="0003"/> if duplicate keys are encountered.
                  </td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">use-first</code></td><td rowspan="1" colspan="1">
                     If duplicate keys are present in a JSON object, all but the first of a set of duplicates are ignored.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">use-last</code></td><td rowspan="1" colspan="1">
                     If duplicate keys are present in a JSON object, all but the last of a set of duplicates are ignored.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">escape?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether special characters are represented in the XDM output in backslash-escaped form.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">
                     Any <termref def="dt-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 <code nobreak="false">fallback</code> function
                        as described below; in the absence of a fallback function, it is replaced by
                        <char>U+FFFD</char>.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">
                     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:
                     <ulist><item><p>all codepoints in the range <char>U+0000</char> to <char>U+001F</char> 
                           or <char>U+007F</char> to <char>U+009F</char>;</p></item><item><p>all codepoints that do not represent 
                           <termref def="dt-permitted-character">permitted characters</termref>,
                           including codepoints representing unpaired surrogates;</p></item><item><p>the character <char>U+005C</char> itself.</p></item></ulist>
                     
                     Such characters are represented using a two-character
                     escape sequence where available (for example, <code nobreak="false">\t</code>), or a six-character escape sequence otherwise
                     (for example <code nobreak="false">\uDEAD</code>). Characters other than these are not escaped in the result, even if they
                     were escaped in the input.
                  </td></tr><tr><td rowspan="2" colspan="1"><p><code nobreak="false">fallback?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">
                  Provides a function which is called when the input contains an escape sequence 
                  that represents a character that is not a <termref def="dt-permitted-character"/>. 
                  It is an error to supply the <code nobreak="false">fallback</code> option if the <code nobreak="false">escape</code>
                  option is present with the value <code nobreak="false">true</code>.
               <ulist><item><p><term>Type: </term><code nobreak="false">(fn(xs:string) as xs:anyAtomicType)?</code></p></item><item><p><term>Default: </term><code nobreak="false">fn { char(0xFFFD) }</code></p></item></ulist></td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">User-supplied function</code></td><td rowspan="1" colspan="1">
                     The function is called when the JSON input contains character that 
                     is not a <termref def="dt-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 <code nobreak="false">liberal:true()</code> is specified):
                     for example <code nobreak="false">\b</code> or <code nobreak="false">\uFFFF</code> or <code nobreak="false">\uDEAD</code>.
                     <p>By default, the escape sequence is replaced with the Unicode
                     <code nobreak="false">REPLACEMENT CHARACTER</code>. The function is <emph>not</emph>
                     called for an escape sequence that is invalid against the grammar (for example <code nobreak="false">\x0A</code>).
                     The string, which results from invoking <function>fn:string</function> 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 <function>fn:error</function>.</p>
                  </td></tr><tr diff="add" at="2024-02-19"><td rowspan="2" colspan="1"><p><code nobreak="false">null?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines how the JSON <code nobreak="false">null</code> value should be represented.<ulist><item><p><term>Type: </term><code nobreak="false">item()*</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">Value</code></td><td rowspan="1" colspan="1">
                     The supplied XDM value is used to represent the JSON <code nobreak="false">null</code> value.
                     The default representation of <code nobreak="false">null</code> is the empty sequence, which works
                     well in cases where setting a property of an object to <code nobreak="false">null</code> has the
                     same meaning as omitting the property. It works less well in cases where <code nobreak="false">null</code>
                     is used with some other meaning, because expressions such as the lookup operator
                     <code nobreak="false">?</code> flatten the result to a single sequence of items,
                     which means that any entries whose value is the empty sequence effectively disappear.
                     The property can be set to any XDM value; a suggested value is the <code nobreak="false">xs:QName</code>
                     value <code nobreak="false">fn:QName("http://www.w3.org/2005/xpath-functions", "null")</code>,
                     which is recognized by the JSON serialization method as representing the JSON value
                     <code nobreak="false">null</code>.
                  </td></tr><tr diff="add" at="A"><td rowspan="2" colspan="1"><p><code nobreak="false">number-parser?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines how numeric values should be processed.<ulist><item><p><term>Type: </term><code nobreak="false">(fn(xs:untypedAtomic) as item()?)?</code></p></item><item><p><term>Default: </term><code nobreak="false">xs:double#1</code></p></item></ulist></td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">User-supplied function</code></td><td rowspan="1" colspan="1">
                     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 <code nobreak="false">xs:double</code> using the XPath casting rules.
                     Supplying the value <code nobreak="false">xs:decimal#1</code> will instead convert to <code nobreak="false">xs:decimal</code>
                     (which potentially retains more precision, but disallows exponential notation), while
                     supplying a function that casts to <code nobreak="false">(xs:decimal | xs:double)</code> will treat
                     the value as <code nobreak="false">xs:decimal</code> if there is no exponent, or as <code nobreak="false">xs:double</code>
                     otherwise. Supplying the value <code nobreak="false">fn:identity#1</code> causes the value to be retained
                     unchanged as an <code nobreak="false">xs:untypedAtomic</code>. 
                     
                     If the <code nobreak="false">liberal</code> option is <code nobreak="false">false</code> (the default), then
                     the supplied <code nobreak="false">number-parser</code> 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 <code nobreak="false">liberal</code>
                     option is <code nobreak="false">true</code> then it is also called if the value conforms to an
                     <termref def="implementation-defined"/> extension of this grammar.
                  </td></tr></tbody></table><p>The various structures that can occur in JSON are transformed recursively to XDM values
            as follows:</p><olist><item><p>A JSON <emph>object</emph> 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 <code nobreak="false">xs:string</code>; 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
                     <code nobreak="false">{ "x": 2, "y": 5 }</code> is transformed to the value
                     <code nobreak="false">{ "x": 2, "y": 5 }</code>.</p><p>If duplicate keys are encountered in a JSON <emph>object</emph>, they are handled
                  as determined by the <code nobreak="false">duplicates</code> option defined above.</p><p>The order of entries is retained.</p></item><item><p>A JSON <emph>array</emph> 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 <code nobreak="false">[ "a", "b", null ]</code> is transformed (by default) to the value
                     <code nobreak="false">[ "a", "b", () ]</code>.</p></item><item><p>A JSON <emph>string</emph> is converted to an <code nobreak="false">xs:string</code> value. 
               <phrase>The handling of special characters depends on the
               <code nobreak="false">escape</code> and <code nobreak="false">fallback</code> options, as described in the table above.</phrase></p></item><item><p>A JSON <emph>number</emph> is <phrase diff="add" at="A">processed using the function supplied
                  in the <code nobreak="false">number-parser</code> option; by default it is</phrase> converted to an <code nobreak="false">xs:double</code> value using
                  the rules for casting from <code nobreak="false">xs:string</code> to <code nobreak="false">xs:double</code>.</p><note><p>The casting rules leave implementations some flexibility as to how values should be handled when they
               are too large to represent as an <code nobreak="false">xs:double</code>. It is <rfc2119>recommended</rfc2119>
               that when parsing JSON, out-of-range values should be converted to positive or negative infinity. 
               This option enables round-tripping
               behavior, since the JSON serialization method represents positive and negative infinity as <code nobreak="false">1e9999</code>
               or <code nobreak="false">-1e9999</code> respectively.</p></note><note><p>Round-tripping of NaN can be achieved by setting the option <code nobreak="false">"null": number("NaN")</code></p></note></item><item><p>The JSON <emph>boolean</emph> values <code nobreak="false">true</code> and <code nobreak="false">false</code> are
                  converted to the corresponding <code nobreak="false">xs:boolean</code> values.</p></item><item><p diff="chg" at="2024-02-19">The JSON value <emph>null</emph> is converted 
                  to the value given by the <code nobreak="false">null</code> option, which defaults to an 
                  empty sequence.</p></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error <errorref class="JS" code="0001"/> occurs if the value of
               <code nobreak="false">$value</code> does not conform to the JSON grammar, unless the option
            <code nobreak="false">"liberal":true()</code> is present and the processor chooses to accept the deviation.</p><p>A dynamic error <errorref class="JS" code="0003"/> occurs if the option
            <code nobreak="false">"duplicates": "reject"</code> is present and the value of
            <code nobreak="false">$value</code> contains a JSON object with duplicate keys.</p><p>A dynamic error <errorref class="JS" code="0005"/> occurs if the <code nobreak="false">$options</code>
            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 <code nobreak="false">fallback</code> when the option <code nobreak="false">"escape":true()</code>
         is also present.</p></def></gitem><gitem><label>Notes</label><def><note><p>The result of the function will be an instance of one of the following types. An
               <code nobreak="false">instance of</code> test (or in XQuery, <code nobreak="false">typeswitch</code>) can be used to
            distinguish them:</p><ulist><item><p><code nobreak="false">map(xs:string, item()?)</code> for a JSON object</p></item><item><p><code nobreak="false">array(item()?)</code> for a JSON array</p></item><item><p><code nobreak="false">xs:string</code> for a JSON string</p></item><item><p><code nobreak="false">xs:double</code> for a JSON number</p></item><item><p><code nobreak="false">xs:boolean</code> for a JSON boolean</p></item><item><p><code nobreak="false">empty-sequence()</code> for a JSON null (or for empty input)</p></item></ulist><p>If the source of the JSON input is a resource accessible by URI, then it may be preferable
         to use the <function>fn:json-doc</function> function. If the source is a binary value (<code nobreak="false">xs:hexBinary</code>
         or <code nobreak="false">xs:base64Binary</code>) then this can first be decoded as a string using the functions
         <function>bin:infer-encoding</function> and <function>bin:decode-string</function>.</p><p>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.</p><p>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 <code nobreak="false">xs:string</code>, which by definition (see <xspecref spec="DM40" ref="xml-and-xsd-versions"/>)
            cannot contain unpaired surrogates.</p><p>The serializer provides an option to output data in <term>json-lines</term> 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 <term>json-lines</term> input, but this can be achieved using the expression
         <code nobreak="false">unparsed-text-lines($uri) =!&gt; parse-json()</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-json('{ "x": 1, "y": [ 3, 4, 5 ] }')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "x": 1e0, "y": [ 3e0, 4e0, 5e0 ] }</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-json('"abcd"')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"abcd"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">parse-json('{ "x": "\\", "y": "\u0025" }')</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">{ "x": "\", "y": "%" }</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json(
  '{ "x": "\\", "y": "\u0025" }',
  { 'escape': true() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "x": "\\", "y": "%" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json(
  '{ "x": "\\", "y": "\u0000" }'
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "x": "\", "y": char(0xFFFD) }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json(
  '{ "x": "\\", "y": "\u0000" }',
  { 'escape': true() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "x": "\\", "y": "\u0000" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json(
  '{ "x": "\\", "y": "\u0000" }',
  { 'fallback': fn($s) { '[' || $s || ']' } }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{ "x": "\", "y": "[\u0000]" }</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json(
  "1984.2",
  { 'number-parser': fn { xs:integer(round(.)) } }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">1984</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json(
  '[ 1, -1, 2 ]',
  { 'number-parser': fn  { boolean(. &gt;= 0) } }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ true(), false(), true() ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">parse-json('[ "a", null, "b" ]',
  { 'null': #fn:null }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "a", #fn:null, "b" ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-json-doc"><head>fn:json-doc</head><changes><change>Additional options are available, as defined by <function>fn:parse-json</function>.</change><change issue="414" PR="546" date="2023-07-25">It is no longer automatically an error if the input
               contains a codepoint that is not valid in XML. Instead, the codepoint
            must be a <termref def="dt-permitted-character"/>. The set of permitted
            characters is <termref def="implementation-defined"/>, but it is
            <rfc2119>recommended</rfc2119> that all Unicode characters should 
               be accepted.</change></changes><glist><gitem><label>Summary</label><def><p>Reads an external resource containing JSON, and returns the result of parsing the resource as JSON.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="json-doc" return-type="item()?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The effect of the two-argument function call <code nobreak="false">fn:json-doc($H, $M)</code>is equivalent to the function composition
            <code nobreak="false">fn:unparsed-text($H) =&gt; fn:parse-json($M)</code>, except that:</p><ulist><item><p>The function may accept a resource in any encoding. [RFC 7159] requires 
               UTF-8, UTF-16, or UTF-32 to be accepted, but it is not an error if a different encoding 
               is used. Unless external encoding information is available, the function must assume 
               that the encoding is one of UTF-8, UTF-16, or UTF-32, and must distinguish these cases 
               by examination of the initial octets of the resource.</p></item><item><p>Having established the encoding, the function must accept any codepoint that
               can validly occur in a JSON text, with the exception of unpaired surrogates.</p></item></ulist><p>If <code nobreak="false">$source</code> is the empty sequence, the function returns the empty sequence.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note></def></gitem><gitem><label>Error Conditions</label><def><p>The function may raise any error defined for the <function>fn:unparsed-text</function> or <function>fn:parse-json</function>
         functions.</p></def></gitem><gitem><label>Notes</label><def><note><p>An initial byte order mark is dropped, as with the <function>fn:unparsed-text</function> function.</p><p>If the input cannot be decoded (that is, converted into a sequence of Unicode codepoints, which may or may not represent characters),
            then a dynamic error occurs as with the <function>fn:unparsed-text</function> function.</p><p>If the input can be decoded,
            then the possibility still arises that the resulting sequence of codepoints includes codepoints that are
            not <termref def="dt-permitted-character">permitted characters</termref>. Such codepoints are translated into JSON escape sequences (for example, <code nobreak="false">\uFFFF</code>),
            and the JSON escape sequence is then passed to the fallback function specified in the <code nobreak="false">$options</code> argument, which in turn
            defaults to a function that returns <char>U+FFFD</char>.</p><p>The function <rfc2119>may</rfc2119> accept a resource in any encoding. <bibref ref="rfc7159"/> requires
               UTF-8, UTF-16, or UTF-32 to be accepted, but it is not an error if a different encoding is used.
               The function detects the encoding using the same rules as the <function>unparsed-text</function>
               function, except that the special handling of media types such as <code nobreak="false">text/xml</code>
            and <code nobreak="false">application/xml</code> may be skipped.</p></note></def></gitem></glist></div3><div3 id="func-json-to-xml"><head>fn:json-to-xml</head><glist><gitem><label>Summary</label><def><p>Parses a string supplied in the form of a JSON text, returning the results in the form
            of an XML <phrase>document node</phrase>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="json-to-xml" return-type="document-node(fn:*)?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The first argument is a JSON text as defined in <bibref ref="rfc7159"/>, in the form of a string. The function
            parses this string to return an XDM node.</p><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>The <code nobreak="false">$options</code> argument can be used to control the way in which the parsing
            takes place. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="liberal" type="xs:boolean" occur="opt"/><arg name="duplicates" type="xs:string" occur="opt"/><arg name="validate" type="xs:boolean" occur="opt"/><arg name="escape" type="xs:boolean" occur="opt"/><arg name="fallback" type="(fn(xs:string) as xs:anyAtomicType)?" occur="opt"/><arg name="number-parser" type="(fn(xs:untypedAtomic) as item()?)?" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="3" colspan="1"><p><code nobreak="false">liberal?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether deviations from the syntax of RFC7159 are permitted.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">
                     The input <rfc2119>must</rfc2119> consist of <phrase>an optional byte order mark (which is ignored) followed by</phrase> a string
                     that conforms to the grammar of <code nobreak="false">JSON-text</code> in <bibref ref="rfc7159"/>. An error <rfc2119>must</rfc2119> be raised
                     (see below) if the input does not conform to the grammar.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">
                     The input <rfc2119>may</rfc2119> contain deviations from the grammar of <bibref ref="rfc7159"/>,
                     which are handled in an <termref def="implementation-defined">implementation-defined</termref> 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 <rfc2119>may</rfc2119> be raised
                     (see below) if the input does not conform to the grammar.
                  </td></tr><tr><td rowspan="4" colspan="1"><p><code nobreak="false">duplicates?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">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 <phrase><code nobreak="false">escape</code> option is set to <code nobreak="false">true</code></phrase>, in which
                  case keys are compared in escaped form. 
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term>If <code nobreak="false">validate</code> is <code nobreak="false">true</code> then <code nobreak="false">reject</code>, otherwise <code nobreak="false">retain</code>.</p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">reject</code></td><td rowspan="1" colspan="1">
                     An error is raised <errorref class="JS" code="0003"/> if duplicate keys are encountered.
                  </td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">use-first</code></td><td rowspan="1" colspan="1">
                     If duplicate keys are present in a JSON object, all but the first of a set of duplicates are ignored.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">retain</code></td><td rowspan="1" colspan="1">
                     If duplicate keys are present in a JSON object, the XML result of the function will also contain duplicates (making
                     it invalid against the schema). This value is therefore incompatible with the option <code nobreak="false">validate=true</code>
                     <errorref class="JS" code="0005"/>
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">validate?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether the generated XML tree is schema-validated.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><termref def="implementation-defined">Implementation-defined</termref>.</p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">
                     Indicates that the resulting XDM instance must be typed; that is, the element
                     and attribute nodes must carry the type annotations that result from validation
                     against the schema given at <specref ref="schema-for-json"/>, or against an
                     <termref def="implementation-defined">implementation-defined</termref> schema 
                     if the <code nobreak="false">liberal</code> option has the value <code nobreak="false">true</code>.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">
                     Indicates that the resulting XDM instance must be untyped.
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">escape?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether special characters are represented in the XDM output 
                  in backslash-escaped form. <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">
                     All characters in the input that are valid
                     in the version of XML supported by the implementation, whether or not they are represented 
                     in the input by means of an escape sequence, are represented as unescaped characters in the result. Any
                     characters or codepoints that are not valid XML characters 
                     (for example, unpaired surrogates) <phrase>are passed to the <code nobreak="false">fallback</code> function
                        as described below; in the absence of a fallback function, they are replaced by
                        the character <char>U+FFFD</char></phrase>.
                     The attributes <code nobreak="false">escaped</code> and <code nobreak="false">escaped-key</code> will not be present in the XDM output.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">
                     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:
                     <ulist><item><p>all codepoints in the range <char>U+0000</char> to <char>U+001F</char> 
                           or <char>U+007F</char> to <char>U+009F</char>;</p></item><item><p>all codepoints that do not represent characters that are valid in the version of XML supported by the processor,
                           including codepoints representing unpaired surrogates;</p></item><item><p>the backslash character itself (<char>U+005C</char>).</p></item></ulist>
                     
                     Such characters are represented using a two-character
                     escape sequence where available (for example, <code nobreak="false">\t</code>), or a six-character escape sequence otherwise
                     (for example <code nobreak="false">\uDEAD</code>). Characters other than these will not be escaped in the result,
                     even if they were escaped in the input. In the result:
                     
                     <ulist><item><p>Any <code nobreak="false">string</code> element whose string value contains a
                           backslash character must have the attribute value <code nobreak="false">escaped="true"</code>.</p></item><item><p>Any element that contains a <code nobreak="false">key</code> attribute whose string value
                           contains a backslash character must have the attribute
                           <code nobreak="false">escaped-key="true"</code>.</p></item><item><p>The values of the <code nobreak="false">escaped</code> and
                           <code nobreak="false">escaped-key</code> attributes are immaterial when there is no backslash
                           present, and it is never necessary to include either attribute when its value
                           is <code nobreak="false">false</code>.</p></item></ulist>
                  </td></tr><tr><td rowspan="2" colspan="1"><p><code nobreak="false">fallback?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">
                  Provides a function which is called when the input contains an escape sequence 
                  that represents a character that is not valid in the version of XML
                  supported by the implementation. 
                  It is an error to supply the <code nobreak="false">fallback</code> option if the <code nobreak="false">escape</code>
                  option is present with the value <code nobreak="false">true</code>.
               <ulist><item><p><term>Type: </term><code nobreak="false">(fn(xs:string) as xs:anyAtomicType)?</code></p></item><item><p><term>Default: </term><code nobreak="false">fn { char(0xFFFD) }</code></p></item></ulist></td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">User-supplied function</code></td><td rowspan="1" colspan="1">
                     The function is called when the JSON input contains an escape sequence
                     that is valid according to the JSON grammar, but which does not represent a
                     character that is valid in the version of XML supported by the processor.
                     In the case of surrogates, it is called once for any six-character escape sequence
                     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 <code nobreak="false">liberal:true()</code> is specified):
                     for example <code nobreak="false">\b</code> or <code nobreak="false">\uFFFF</code> or <code nobreak="false">\uDEAD</code>.
                     <p>By default, the escape sequence is replaced with the Unicode
                     <code nobreak="false">REPLACEMENT CHARACTER</code>. The function is <emph>not</emph>
                     called for an escape sequence that is invalid against the grammar (for example <code nobreak="false">\x0A</code>). 
                     The string, which results from invoking <function>fn:string</function> 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 <function>fn:error</function>.</p>
                  </td></tr><tr diff="add" at="A"><td rowspan="2" colspan="1"><p><code nobreak="false">number-parser?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines how numeric values should be processed.<ulist><item><p><term>Type: </term><code nobreak="false">(fn(xs:untypedAtomic) as item()?)?</code></p></item><item><p><term>Default: </term><code nobreak="false">xs:identity#1</code></p></item></ulist></td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">User-supplied function</code></td><td rowspan="1" colspan="1">
                     The supplied function is called to process the string value of any JSON number
                     in the input. The string value of the <code nobreak="false">number</code> element generated in
                     the result will be the value obtained by calling the supplied function, and
                     then converting its result to a string by calling <code nobreak="false">fn:string#1</code>.
                     <p>By default, numbers are represented in the XML output exactly as they
                        were written in the input.
                     Supplying the value <code nobreak="false">xs:double#1</code> will cause the value to be
                        convered to type <code nobreak="false">xs:double</code> (which will then be represented
                        in the XML by converting the <code nobreak="false">xs:double</code> to a string).
                        Similarly <code nobreak="false">xs:decimal#1</code> will convert to <code nobreak="false">xs:decimal</code>
                     (which potentially retains more precision, but disallows exponential notation), while
                     supplying a function that casts to <code nobreak="false">(xs:decimal | xs:double)</code> will treat
                     the value as <code nobreak="false">xs:decimal</code> if there is no exponent, or as <code nobreak="false">xs:double</code>
                     otherwise. The default value <code nobreak="false">fn:identity#1</code> causes the value to be retained
                     unchanged as an <code nobreak="false">xs:untypedAtomic</code>. Before calling the supplied <code nobreak="false">number-parser</code>,
                     the value is first checked to ensure that it conforms to the JSON grammar (for example,
                     a leading plus sign and redundant leading zeroes are not allowed); these checks are disabled
                     if the <code nobreak="false">liberal</code> option is set to <code nobreak="false">true</code>. Note that the
                     option <code nobreak="false">validate=true</code> will cause the result to be validated
                     as type <code nobreak="false">xs:double</code> (disallowing NaN and infinity).</p>
                  </td></tr></tbody></table><p>The various structures that can occur in JSON are transformed recursively to XDM values
            according to the rules given in <specref ref="json-to-xml-mapping"/>.</p><p>The function returns a document node, whose only child
               is the element node representing the outermost construct in the JSON
            text.</p><p>The function is <termref def="dt-nondeterministic">nondeterministic with respect to node identity</termref>: that is, if the function is called twice with the same
            arguments, it is <termref def="implementation-dependent">implementation-dependent</termref> whether the same node is returned on both
            occasions.</p><p>The base URI of the returned document node is taken from the 
            <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> of the
            function call.</p><p>The choice of namespace prefix (or absence of a prefix) in the names of constructed
         nodes is <termref def="implementation-dependent">implementation-dependent</termref>.</p><p>The XDM tree returned by the function does not contain any
         unnecessary (albeit valid) nodes such as whitespace text nodes, comments, or processing instructions.
         It does not include any whitespace in the value of <code nobreak="false">number</code> or <code nobreak="false">boolean</code> 
            element nodes, nor in the value of <code nobreak="false">escaped</code> or <code nobreak="false">escaped-key</code>
         attribute nodes.</p><p>If the result is typed, every element named <code nobreak="false">string</code> will have an attribute named 
            <code nobreak="false">escaped</code> whose value is either <code nobreak="false">true</code> or <code nobreak="false">false</code>, and every element having 
            an attribute named <code nobreak="false">key</code> will also have an attribute named <code nobreak="false">escaped-key</code> whose value is either 
            <code nobreak="false">true</code> or <code nobreak="false">false</code>.
         </p><p>If the result is untyped, the attributes <code nobreak="false">escaped</code> and <code nobreak="false">escaped-key</code> will 
            either be present with the value <code nobreak="false">true</code>, or will be absent. They will never be present with the value <code nobreak="false">false</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>An error is raised <errorref spec="FO" class="JS" code="0001"/> if the value of
            <code nobreak="false">$value</code> does not conform to the JSON grammar as defined
            by <bibref ref="rfc7159"/>, unless the option <code nobreak="false">"liberal":true()</code> is present and
            the processor chooses to accept the deviation. </p><p>An error is raised <errorref spec="FO" class="JS" code="0004"/> if the value of
            the <code nobreak="false">validate</code> option is <code nobreak="false">true</code> and the processor does not support
            schema validation or typed data.</p><p>An error is raised <errorref spec="FO" class="JS" code="0005"/> if the value of
            <code nobreak="false">$options</code> includes an entry whose key is defined in this specification,
               and whose value is not a permitted value for that key.</p></def></gitem><gitem><label>Notes</label><def><note><p>To read a JSON file, this function can be used in conjunction with the
               <function>fn:unparsed-text</function> function.</p><p>Many JSON implementations allow commas to be used after the last item in an object or
            array, although the specification does not permit it. The option
               <code nobreak="false">spec="liberal"</code> is provided to allow such deviations from the
            specification to be accepted. Some JSON implementations also allow constructors such as
               <code nobreak="false">new Date("2000-12-13")</code> to appear as values: specifying
               <code nobreak="false">spec="liberal"</code> allows such extensions to be accepted, but does not
            guarantee it. If such extensions are accepted, the resulting value is
            implementation-defined, and will not necessarily conform to the schema at <specref ref="schema-for-json"/>.</p><p>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.</p><p>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 the only possibility because the input to the function
         is an instance of <code nobreak="false">xs:string</code>, which by definition can contain only those characters that are valid in XML.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">json-to-xml(
  '{ "x": 1, "y": [ 3, 4, 5 ] }',
  { "validate": false() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;map xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;number key="x"&gt;1&lt;/number&gt;
  &lt;array key="y"&gt;
   &lt;number&gt;3&lt;/number&gt;
   &lt;number&gt;4&lt;/number&gt;
   &lt;number&gt;5&lt;/number&gt;
  &lt;/array&gt;
&lt;/map&gt;</eg><p>(with whitespace added for legibility)</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">json-to-xml(
  '"abcd"',
  { 'liberal': false() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">&lt;string xmlns="http://www.w3.org/2005/xpath-functions"&gt;abcd&lt;/string&gt;</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">json-to-xml(
  '{ "x": "\\", "y": "\u0025" }',
  { "validate": false() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;map xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;string key="x"&gt;\&lt;/string&gt;
  &lt;string key="y"&gt;%&lt;/string&gt;
&lt;/map&gt;</eg><p>(with whitespace added for legibility)</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">json-to-xml(
  '{ "x": "\\", "y": "\u0025" }',
  { 'escape': true(), "validate": false() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;map xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;string escaped="true" key="x"&gt;\\&lt;/string&gt;
  &lt;string key="y"&gt;%&lt;/string&gt;
&lt;/map&gt;</eg><p>(with whitespace added for legibility)</p><p><emph>(But see the detailed rules for alternative values of the <code nobreak="false">escaped</code> attribute
                  on the second <code nobreak="false">string</code> element.)</emph></p></td></tr><tr><td colspan="2" rowspan="1"><p>The following example illustrates use of the <code nobreak="false">fallback</code> function to
               handle characters that are invalid in XML.</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">
let $json := unparsed-text('http://example.com/endpoint')
let $options := {
  'liberal': true(),
  'fallback': fn($char as xs:string) as xs:string {
    let $c0chars := {
      '\u0000': '[NUL]',
      '\u0001': '[SOH]',
      '\u0002': '[STX]',
      ...
      '\u001E': '[RS]',
      '\u001F': '[US]'
    }
    let $replacement := $c0chars($char)
    return if (exists($replacement)) then (
      $replacement
    ) else (
      error( #err:invalid-char,
        'Error: ' || $char || ' is not a C0 control character.'
      )
    )
  }
}
return json-to-xml($json, $options)</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-xml-to-json"><head>fn:xml-to-json</head><changes><change issue="1347" PR="1353" date="2024-09-03">An option has been added to suppress the escaping 
            of the solidus (forwards slash) character.</change><change issue="1445" PR="1455" date="2024-10-01">Numbers now retain their original lexical form, except for
         any changes needed to satisfy JSON syntax rules (for example, stripping leading zero digits).</change></changes><glist><gitem><label>Summary</label><def><p>Converts an XML tree, whose format corresponds to the XML representation of JSON defined
            in this specification, into a string conforming to the JSON grammar.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="xml-to-json" return-type="xs:string?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="node()?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The first argument <code nobreak="false">$node</code> is a node; the subtree rooted at this node will typically be
            the XML representation of a JSON document as defined in <specref ref="json-to-xml-mapping"/>.</p><p>If <code nobreak="false">$node</code> is the empty sequence, the function returns the empty sequence.</p><p>The <code nobreak="false">$options</code> argument can be used to control the way in which the conversion
            takes place. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="escape-solidus" type="xs:boolean" occur="opt"/><arg name="indent" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="3" colspan="1"><p><code nobreak="false">escape-solidus?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether the character <char>U+002F</char> should be escaped 
                  as <code nobreak="false">\/</code>. By default the character is escaped, but this is only necessary
                  when the resulting JSON is embedded in HTML.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">
                     The character <char>U+002F</char> is output as is, without escaping.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">
                     The character <char>U+002F</char> is escaped by preceding it with <char>U+005C</char>. 
                  </td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">indent?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether additional whitespace should be added to the output to improve readability.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">
                     The processor must not insert any insignificant whitespace between JSON tokens.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">
                     The processor <rfc2119>may</rfc2119> insert whitespace between JSON tokens in order to improve readability.
                     The specification imposes no constraints on how this is done.
                  </td></tr></tbody></table><p>The node supplied as <code nobreak="false">$node</code> must be one of the following: <errorref spec="FO" class="JS" code="0006"/></p><olist><item><p>An element node whose name matches the name of a global element declaration in the schema given in 
               <specref ref="schema-for-json"/> (“the schema”) and that is valid as defined below:</p><olist><item><p>If the type annotation of the element matches the type of the relevant element declaration 
                     in the schema (indicating that the element has been validated against the schema), then the element 
                     is considered valid.
                  </p></item><item><p>Otherwise, the processor <rfc2119>may</rfc2119> attempt to validate the element against
                     the schema, in which case it is treated as valid if and only if the outcome of validation is
                     <term>valid</term>.
                  </p></item><item><p>Otherwise (if the processor does not attempt validation using the schema), 
                     the processor <rfc2119>must</rfc2119> ensure that the content of the element, 
                     after stripping all attributes (at any depth) in namespaces other than 
                     <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>, is such that validation 
                     against the schema would have an outcome of <term>valid</term>.
                  </p><note><p>The process described here is not precisely equivalent to schema validation. 
                        For example, schema validation will fail if there is an invalid <code nobreak="false">xsi:type</code> 
                        or <code nobreak="false">xsi:nil</code> attribute, whereas this process will ignore such attributes.
                     </p></note></item></olist></item><item><p>An element node <var>E</var> having a <code nobreak="false">key</code> attribute and/or an <code nobreak="false">escaped-key</code> attribute 
               provided that <var>E</var> would satisfy one of the above
            conditions if the <code nobreak="false">key</code> and/or <code nobreak="false">escaped-key</code> attributes were removed.</p></item><item><p>A document node having exactly one element child and no text node children, 
               where the element child satisfies one of the conditions above.</p></item></olist><p>Furthermore, <code nobreak="false">$node</code> must satisfy the following constraint
            (which cannot be conveniently expressed in the schema). Every element <var>M</var> that is a descendant-or-self of 
            <code nobreak="false">$node</code> and has local name <code nobreak="false">map</code> and namespace URI <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>
            must satisfy the following rule: there must not be two distinct children of <var>M</var> (say <var>C/1</var> and <var>C/2</var>) 
            such that the normalized key of <var>C/1</var> is equal to the normalized key of <var>C/2</var>. The normalized key 
            of an element <var>C</var> is as follows:</p><ulist><item><p>If <var>C</var> has the attribute value <code nobreak="false">escaped-key="true"</code>, then the value of the 
               <code nobreak="false">key</code> attribute of <var>C</var>, with all JSON escape sequences replaced by the corresponding Unicode characters 
               according to the JSON escaping rules.
            </p></item><item><p>Otherwise (the <code nobreak="false">escaped-key</code> attribute of <var>C</var> is absent or set to <code nobreak="false">false</code>), 
               the value of the <code nobreak="false">key</code> attribute of <var>C</var>.</p></item></ulist><p>Nodes in the input tree are handled by applying the following rules, recursively. In these rules the phrase
            “an element named <var>N</var>” means “an element node whose local name is <var>N</var> and whose namespace URI is 
            <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>”.</p><olist><item><p>A document node having a single element node child is processed by processing that child.</p></item><item><p>An element named <code nobreak="false">null</code> results in the output <code nobreak="false">null</code>.</p></item><item><p>An element <code nobreak="false">$E</code> named <code nobreak="false">boolean</code> results in the output <code nobreak="false">true</code> or <code nobreak="false">false</code>
            depending on the result of <phrase><code nobreak="false">xs:boolean(fn:string($E))</code></phrase>.</p></item><item><p>An element <code nobreak="false">$E</code> named <code nobreak="false">number</code> is processed as follows.</p><p>The input is required to conform to the XSD rules defining a valid instance of <code nobreak="false">xs:double</code>
               (excluding infinity and <code nobreak="false">NaN</code>), while the output is required to conform to the
               JSON rules defining a valid JSON number. These rules are slightly different.</p><p>Specifically, the XSD rules require the value (after removing leading and trailing whitespace)
                  to match the regular expression:</p><eg xml:space="preserve">(\+|-)?([0-9]+(\.[0-9]*)?|\.[0-9]+)([Ee](\+|-)?[0-9]+)?</eg><p>while the JSON rules require:</p><eg xml:space="preserve">-?(0|[1-9][0-9]*)(\.[0-9]+)?([Ee](\+|-)?[0-9]+)?</eg><p>If the input value does not match the required JSON format, it must therefore be adjusted
               by applying the following steps:</p><ulist><item><p>Remove leading and trailing whitespace.</p></item><item><p>Remove any leading plus sign.</p></item><item><p>Remove any leading zero digits in the integer part, while ensuring that at
                        least one digit remains.</p></item><item><p>If there is a decimal point that is not preceded by a digit, add a zero digit 
                        before the decimal point.</p></item><item><p>If there is a decimal point that is not followed by a digit, add a zero digit 
                        after the decimal point.</p></item></ulist><note><p>The output uses exponential notation if and only if the input uses exponential notation.</p><p>The rules have changed since version 3.1 of this specification. In previous versions, the supplied
                     number was cast to an <code nobreak="false">xs:double</code>, and then serialized using the rules of the 
                     <function>fn:string</function> function. This resulted in JSON numbers using exponential notation
                     for values outside the range 1e-6 to 1e6, and led to a loss of precision for 64-bit integer
                     values.                 
                  </p></note></item><item><p>An element named <code nobreak="false">string</code> results in the output of the string value of the element, enclosed in
            quotation marks, with any special characters in the string escaped as described below.</p></item><item><p>An element named <code nobreak="false">array</code> results in the output of the children of the <code nobreak="false">array</code> element, 
               each processed by applying these rules recursively: the items in the resulting list are enclosed between square brackets, 
               and separated by commas.</p></item><item><p>An element named <code nobreak="false">map</code> results in the output of a sequence of map entries corresponding to 
               the children of the <code nobreak="false">map</code> element, enclosed between curly braces and separated by commas. 
               Each entry comprises the value of the <code nobreak="false">key</code> attribute of the child element, enclosed in quotation marks 
               and escaped as described below, followed by a colon, followed by the result of processing the child element 
               by applying these rules recursively. The order of properties in the output JSON representation retains the order
               of the children of the <code nobreak="false">map</code> element.</p></item><item><p>Comments, processing instructions, and whitespace text node children of <code nobreak="false">map</code> and <code nobreak="false">array</code>
               are ignored.</p></item></olist><p>Strings are escaped as follows:</p><olist><item><p>If the attribute <code nobreak="false">escaped="true"</code> is present for a string value, or <code nobreak="false">escaped-key="true"</code> for a key value, then:</p><olist><item><p>any valid JSON escape sequence present in the string is copied unchanged to the output;</p></item><item><p>any invalid JSON escape sequence results in a dynamic error <errorref spec="FO" class="JS" code="0007"/>;</p></item><item><p>any unescaped occurrence of <char>U+0022</char>, <char>U+0008</char>, <char>U+000C</char>, 
                        <char>U+000A</char>, <char>U+000D</char>, <char>U+0009</char>, or 
                        (subject to the <code nobreak="false">escape-solidus</code> option) <char>U+002F</char> is replaced by
                  <code nobreak="false">\"</code>, <code nobreak="false">\b</code>, <code nobreak="false">\f</code>, <code nobreak="false">\n</code>, <code nobreak="false">\r</code>, <code nobreak="false">\t</code>, <phrase>or <code nobreak="false">\/</code></phrase> respectively; </p></item><item><p>any other codepoint in the range 1-31 or 127-159 is replaced by an escape in the form \uHHHH where HHHH 
                  is the upper-case hexadecimal representation of the codepoint value.</p></item></olist></item><item><p>Otherwise (that is, in the absence of the attribute <code nobreak="false">escaped="true"</code> for a string value, 
            or <code nobreak="false">escaped-key="true"</code> for a key value):</p><olist><item><p>any occurrence of backslash is replaced by <code nobreak="false">\\</code></p></item><item><p>any occurrence of 
                        <char>U+0022</char>, <char>U+0008</char>, <char>U+000C</char>, 
                        <char>U+000A</char>, <char>U+000D</char>, or <char>U+0009</char> is 
               replaced by <code nobreak="false">\"</code>, <code nobreak="false">\b</code>, <code nobreak="false">\f</code>, <code nobreak="false">\n</code>, 
                        <code nobreak="false">\r</code>, or <code nobreak="false">\t</code> respectively; </p></item><item><p>any other codepoint in the range 1-31 or 127-159 is replaced by an escape in 
            the form <code nobreak="false">\uHHHH</code> where <code nobreak="false">HHHH</code> is the upper-case hexadecimal representation of the codepoint value.</p></item></olist></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref spec="FO" class="JS" code="0005"/> if the value of 
            <code nobreak="false">$options</code> includes an entry whose key is defined in this specification, 
            and whose value is not a permitted value for that key.</p><p>A dynamic error is raised <errorref spec="FO" class="JS" code="0006"/> if the value of
            <code nobreak="false">$node</code> is not a document or element node or is not valid according to the schema for the XML representation of
            JSON<phrase>, or if a <code nobreak="false">map</code> element has two children whose normalized key values are the same.</phrase></p><p>A dynamic error is raised <errorref spec="FO" class="JS" code="0007"/> if the value of
            <code nobreak="false">$node</code> includes a string labeled with <code nobreak="false">escaped="true"</code>, or
            a key labeled with <code nobreak="false">escaped-key="true"</code>, where the content of the string or key
            contains an invalid JSON escape sequence: specifically, where it contains a backslash (<code nobreak="false">\</code>) that is not followed by one
            of the characters <code nobreak="false">"</code>, <code nobreak="false">\</code>, <code nobreak="false">/</code>, <code nobreak="false">b</code>, <code nobreak="false">f</code>, <code nobreak="false">n</code>, 
            <code nobreak="false">r</code>, <code nobreak="false">t</code>, or <code nobreak="false">u</code>, or where it contains the characters <code nobreak="false">\u</code>
            not followed by four hexadecimal digits (that is <code nobreak="false">[0-9A-Fa-f]{4}</code>).
        </p></def></gitem><gitem><label>Notes</label><def><note><p>The rule requiring schema validity has a number of consequences, including the following:</p><olist><item><p>The input cannot contain no-namespace attributes, or attributes in the namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>,
            except where explicitly allowed by the schema. Attributes in other namespaces, however, are ignored.</p></item><item><p>Nodes that do not affect schema validity, such as comments, processing instructions, namespace nodes, and whitespace text node
            children of <code nobreak="false">map</code> and <code nobreak="false">array</code>, are ignored.</p></item><item><p>Numeric values are restricted to those that are valid in JSON: 
            the schema disallows positive and negative infinity and <code nobreak="false">NaN</code>.</p></item><item><p>Duplicate key values are not permitted. <phrase>Most cases of duplicate keys are prevented by the rules in the schema; 
            additional cases (where the keys are equal only after expanding JSON escape sequences) are prevented by the prose rules 
            of this function. For example, the key values <code nobreak="false">\n</code> and <code nobreak="false">\u000A</code> are treated as duplicates even though
            the rules in the schema do not treat them as such.</phrase></p></item></olist><p>The rule allowing the top-level element to have a <code nobreak="false">key</code> attribute (which is ignored)
         allows any element in the output of the <function>fn:json-to-xml</function> function
         to be processed: for example, it is possible to take a JSON document, convert it to XML, select
         a subtree based on the value of a <code nobreak="false">key</code> attribute, and then convert this subtree
         back to JSON, perhaps after a transformation. The rule means that an element with the appropriate name will be 
            accepted if it has been validated against one of the 
            types <code nobreak="false">mapWithinMapType</code>, <code nobreak="false">arrayWithinMapType</code>, <code nobreak="false">stringWithinMapType</code>, 
            <code nobreak="false">numberWithinMapType</code>, <code nobreak="false">booleanWithinMapType</code>, or <code nobreak="false">nullWithinMapType</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>The input <code nobreak="false">&lt;array xmlns="http://www.w3.org/2005/xpath-functions"&gt;&lt;number&gt;1&lt;/number&gt;&lt;string&gt;is&lt;/string&gt;&lt;boolean&gt;1&lt;/boolean&gt;&lt;/array&gt;</code>
         produces the result <code nobreak="false">[ 1, "is", true ]</code>.</p></td></tr><tr><td colspan="2" rowspan="1"><p>The input <code nobreak="false">&lt;map xmlns="http://www.w3.org/2005/xpath-functions"&gt;&lt;number key="Sunday"&gt;1&lt;/number&gt;&lt;number key="Monday"&gt;2&lt;/number&gt;&lt;/map&gt;</code>
            produces the result <code nobreak="false">{ "Sunday": 1, "Monday": 2 }</code>.</p></td></tr><tr><td colspan="2" rowspan="1"><p>The input <code nobreak="false">&lt;array xmlns="http://www.w3.org/2005/xpath-functions"&gt;&lt;number&gt;10&lt;/number&gt;&lt;number&gt;17e2&lt;/number&gt;&lt;number&gt;0005&lt;/number&gt;&lt;/array&gt;</code>
            produces the result <code nobreak="false">[ 10, 17e2, 5 ]</code>.</p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="csv-functions"><head>Functions on CSV Data</head><changes><change issue="413" PR="533 719 834">
                  New functions are available for processing input data in CSV (comma separated values) format.
               </change></changes><p>This section describes functions that parse CSV data.</p><p><termdef id="dt-csv" term="CSV"> The term <term>comma separated values</term> or 
               <term>CSV</term> refers to a wide variety of plain-text tabular data formats with
               fields and records separated by standard character delimiters 
               (often, but not invariably, commas).</termdef></p><p>A CSV is a 2-dimensional tabular data structure consisting of multiple <term>rows</term> 
               (also known as <term>records</term>). Each
               row contains multiple <term>fields</term>. Fields occupying the same position in
               successive rows constitute a <term>column</term>. Columns are identified by position and
               optionally by name. Column names can be
               assigned within a CSV using an optional <term>header row</term>.</p><p>CSV has developed informally for decades, and many variations are found. 
               This specification refers to <bibref ref="rfc4180"/>,
               which provides a standardized grammar. This specification extends the
               grammar defined in <bibref ref="rfc4180"/> as follows:</p><ulist><item><p>This specification uses the term <term>row</term> where RFC 4180 uses
               <term>record</term>.</p></item><item><p>Line endings are normalized: specifically, the character sequences
               <char>U+000D</char>, or <char>U+000D</char> followed by <char>U+000A</char>, are converted
                  to a single <char>U+000A</char> character. This applies whether or not the line ending
               appears within a quoted string, and whether or not <char>U+000A</char> is the chosen
               row delimiter.</p></item><item><p>Row delimiters other than newline are recognized.</p></item><item><p>Field delimiters other than <char>U+002C</char> are recognized.</p></item><item><p>Quote characters other than <char>U+0022</char> are recognized.</p></item><item><p>Non-ASCII characters are recognized.</p></item></ulist><p>This specification defines a 
               mapping from this extended grammar
               to constructs in the XDM model, and provides illustrative examples of how these
               constructs can be combined with other language features to process CSV data.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:csv-to-arrays</code></td><td rowspan="1" colspan="1">Parses CSV data supplied as a string, returning the results in the form of a sequence
            of arrays of strings.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:parse-csv</code></td><td rowspan="1" colspan="1">Parses CSV data, returning the results in the form of a record containing information about the
            names in the header, as well as the data itself.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:csv-doc</code></td><td rowspan="1" colspan="1">Reads an external resource containing CSV, and returns the results as a record
            containing information about the names in the header, as well as the data itself.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:csv-to-xml</code></td><td rowspan="1" colspan="1">Parses CSV data supplied as a string, returning the results as an XML document, as described by
            <specref ref="csv-represent-as-xml"/>.</td></tr></tbody></table><p>The most basic function for parsing CSV is <function>fn:csv-to-arrays</function>
            which recognizes the delimiters for rows and fields and returns a sequence
            of arrays each corresponding to one row. The fields within each array are
            represented as instances of <code nobreak="false">xs:string</code>.</p><p>The other two functions recognize column names, and make it easier to address
            individual fields using these names. The <code nobreak="false">parse-csv</code> function
            delivers this capability using XDM maps and functions, while <code nobreak="false">csv-to-xml</code>
            function represents the information using XDM element nodes.</p><div3 id="csv-delimiters"><head>CSV delimiters</head><p>The delimiters used for rows, columns, and quoting are configurable. An error
                  is raised if the same delimiter string is used in multiple roles 
                  <errorref class="CV" code="0003"/>.</p><p>Rows in CSV files are typically delimited with CRLF (<char>U+000D</char>, <char>U+000A</char>), 
                     LF (<char>U+000A</char>), or CR (<char>U+000D</char>) line endings, 
                     although RFC 4180 specifies CRLF. The CSV parsing functions 
                     normalize these line endings to LF (<char>U+000A</char>).
                     They therefore use LF as the default row delimiter.
                  </p><p>The last row in the file may or may not be followed by a row delimiter.
                  the empty file is treated as containing zero rows, while a file consisting solely
                  of a row delimiter is treated as containing one empty row. In all other cases,
                  a file that does not end with a row delimiter is treated as if a row delimiter were
                  added at the end.</p><p>Fields in CSV are frequently delimited with a comma. Other field
                     delimiters are useful, for
                     example when numeric data uses comma as a decimal separator. The
                     chosen field delimiter is then often <char>U+003B</char>
                     or <char>U+0009</char>.</p><p>The column delimiter thus defaults to <char>U+002C</char>. 
                     The value may be
                     any single Unicode character. An error is raised if the 
                     <code nobreak="false">column-delimiter</code> option is set to a multi-character string.</p></div3><div3 id="csv-field-quoting"><head>Field quoting</head><p>CSVs, as specified in <bibref ref="rfc4180"/>, require that fields be wrapped 
                  with a quote character if they
                  contain either the row or column delimiter. For example:</p><eg xml:space="preserve">"A single field, containing a comma","another field containing CRLF
                  within it"</eg><p>If a field is to contain the quote character, the character must be escaped by doubling it, 
                  as with escaping of quotes in XPath string literals (see <xspecref ref="id-literals" spec="XP40"/>). An error is raised
                  <errorref class="CV" code="0001"/> if a quote character appears within a field
                  incorrectly escaped, for example:</p><eg xml:space="preserve">incorrectly escaped " quote character</eg><p>The quotes surrounding quoted fields are not included in the result. The
                  following input string, when parsed, produces a sequence of strings, as shown
                  below:</p><eg xml:space="preserve">'"Field 1","Field 2","Field ""with quotes"" 3"'</eg><eg xml:space="preserve">('Field 1', 'Field 2', 'Field "with quotes" 3')</eg><p>The quote character defaults to <char>U+0022</char>.</p><p>No space is allowed between the column delimiter and a quote. An error is raised
                     <errorref class="CV" code="0001"/> if
                     whitespace or other characters occur between a quote character and the nearest
                     column delimiter.</p><p>The following example is therefore invalid and parsing it will raise an error.</p><eg xml:space="preserve">'"Field 1", "Field 2", "Field 3"'</eg></div3><div3 id="basic-csv-to-xdm-mapping"><head>Basic parsing of CSV to arrays</head><p>The result of <function>fn:csv-to-arrays</function> is a sequence of rows, where
                  each row is represented as an array of <code nobreak="false">xs:string</code> values.</p><p>The first row of the CSV is returned in the same way as all the other rows.
                  <function>fn:csv-to-arrays</function> does not distinguish between a header row and data
                  rows, and returns all of them.</p><example><head>A CSV with fixed-width rows</head><p>For example, given the input:</p><eg xml:space="preserve">
'Column 1,Column 2,Column 3
Field 1A,Field 1B,Field 1C
Field 2A,Field 2B,Field 2C'
               </eg><p>the <function>fn:csv-to-arrays</function> function produces</p><eg xml:space="preserve">
(
  [ "Column 1", "Column 2", "Column 3" ],
  [ "Field 1A", "Field 1B", "Field 1C" ],
  [ "Field 2A", "Field 2B", "Field 2C" ]
)
               </eg></example><example><head>A CSV with variable-width rows</head><p>It is common practice for all rows in a CSV to
                  have the same number of columns, but this is not required.</p><eg xml:space="preserve">
'Column 1,Column 2,Column 3
Field 1A,Field 1B,Field 1C
Field 2A,Field 2B,Field 2C,Field 2D'
               </eg><p>produces</p><eg xml:space="preserve">
(
  [ "Column 1", "Column 2", "Column 3" ],
  [ "Field 1A", "Field 1B", "Field 1C" ],
  [ "Field 2A", "Field 2B", "Field 2C", "Field 2D" ]
)
               </eg><p><bibref ref="rfc4180"/> states that CSVs <rfc2119>should</rfc2119> contain the
                  same number of fields in each row, so that there are a uniform number of columns.
                  However, the reality is that CSVs can, and sometimes do, contain a variable number
                  of fields in a row. As a result, this function does
                  not truncate or pad the number of fields in each row for any reason.
                  The <function>fn:csv-to-xml</function> and <function>fn:parse-csv</function> functions provide
                  facilities to enforce uniformity and an expected number of
                  columns.</p></example></div3><div3 id="func-csv-to-arrays"><head>fn:csv-to-arrays</head><changes><change PR="533 719 834 1066" issue="413 1052" date="2023-07-25">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Parses CSV data supplied as a string, returning the results in the form of a sequence
            of arrays of strings.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="csv-to-arrays" return-type="array(xs:string)*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The <code nobreak="false">$value</code> argument is CSV data, as defined in <bibref ref="rfc4180"/>, in the form of an
            <code nobreak="false">xs:string</code> value. The function parses this string,
            after normalizing newlines so that <char>U+000D</char> and (<char>U+000D</char>, <char>U+000A</char>)
            sequences are converted to <char>U+000A</char>.
            The result of the function is a sequence of arrays of strings, that is
            <code nobreak="false">array(xs:string)*</code>; each array represents one row of the CSV input.</p><p>If <code nobreak="false">$value</code> is the empty sequence or a zero-length string, the 
            function returns the empty sequence.</p><p>The <code nobreak="false">$options</code> argument can be used to control the way in which the parsing
            takes place. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="field-delimiter" type="xs:string" occur="opt"/><arg name="row-delimiter" type="xs:string" occur="opt"/><arg name="quote-character" type="xs:string" occur="opt"/><arg name="trim-whitespace" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">field-delimiter?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The character used to delimit fields within a record. An instance of
                  <code nobreak="false">xs:string</code> whose length is exactly one.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">","</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">row-delimiter?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The character used to delimit rows within
                  the CSV string. An instance of
                  <code nobreak="false">xs:string</code> whose length is exactly one.
                  Defaults to a single newline character (<char>U+000A</char>).<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">char('\n')</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">quote-character?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The character used to quote fields within the CSV string. An instance of
                  <code nobreak="false">xs:string</code> whose length is exactly one.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">'"'</code></p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">trim-whitespace?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether leading and trailing whitespace
                  is removed from the content of unquoted fields.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">Unquoted fields will be returned with any leading or trailing
                     whitespace intact.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">Unquoted fields will be returned with leading or trailing
                     whitespace removed, and all other whitespace preserved.
                  </td></tr></tbody></table><p>An empty field is represented by a zero-length string. An empty field is deemed to exist
         when a field delimiter immediately follows either another field delimiter, or
         a row delimiter, or the start of <code nobreak="false">$value</code>; or when a row delimiter or the
         end of <code nobreak="false">$value</code> immediately follows a field delimiter.</p><p>A blank row is represented as the empty array (not as an
            array containing a single empty field). A blank row is deemed to exist when a
            row delimiter immediately follows either another row delimiter or the start of <code nobreak="false">$value</code>,
         after trimming of whitespace if the <code nobreak="false">trim-whitespace</code> option is <code nobreak="false">true</code>.
         No blank row occurs after the final row delimiter.</p><p>If <code nobreak="false">$value</code> is a zero-length string, the CSV is considered to
         contain no rows; while if <code nobreak="false">$value</code> consists of a single row delimiter,
         it is considered to contain a single blank row. The presence or
         absence of a final row delimiter generally has no effect on the result,
         except when it appears at the start of the input, in which case it causes a
         single blank row to exist.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error <errorref class="CV" code="0001"/> occurs if the value of
            <code nobreak="false">$csv</code> does not conform to the required grammar.</p><p>A dynamic error <errorref class="CV" code="0002"/> occurs if the value of the
            <code nobreak="false">field-delimiter</code>, <code nobreak="false">row-delimiter</code>, or 
            <code nobreak="false">quote-character</code> option is not a single character.</p><p>A dynamic error <errorref class="CV" code="0003"/> occurs if the same character
            is used for more than one of the
            <code nobreak="false">field-delimiter</code>, <code nobreak="false">row-delimiter</code>, and
            <code nobreak="false">quote-character</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The default row delimiter is a single newline character <char>U+000A</char>. 
            Alternative line endings
            such as <code nobreak="false">CR</code> and <code nobreak="false">CRLF</code> will already have been normalized to a single
            newline. </p><p>All fields are returned as <code nobreak="false">xs:string</code> values.</p><p>Quoted fields in the input are returned without the quotes.</p><p>The first row is not treated specially.</p><p>For more discussion of the returned data, see <specref ref="basic-csv-to-xdm-mapping"/>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>Handling trivial input:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(())</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays("")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(char('\n'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(" ", { 'trim-whitespace': true() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(" ", { 'trim-whitespace': false() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ " " ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(` { char('\n') }`, { 'trim-whitespace': true() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(` { char('\n') }`, { 'trim-whitespace': false() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ " " ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(`{ char('\n') } `, { 'trim-whitespace': true() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(`{ char('\n') } `, { 'trim-whitespace': false() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[], [ " " ]</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Using newline separators:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(
  `name,city{ char('\n') }` ||
  `Bob,Berlin{ char('\n') }` ||
  `Alice,Aachen{ char('\n') }`
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "name", "city" ],
[ "Bob", "Berlin" ],
[ "Alice", "Aachen" ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $CRLF := `{ char('\r') }{ char('\n') }`
return csv-to-arrays(
  `name,city{ $CRLF }` ||
  `Bob,Berlin{ $CRLF }` ||
  `Alice,Aachen{ $CRLF }`
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "name", "city" ],
[ "Bob", "Berlin" ],
[ "Alice", "Aachen" ]</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Quote handling:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(
  string-join(
    (`"name","city"`, `"Bob","Berlin"`, `"Alice","Aachen"`),
    char('\n')
  )
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "name", "city" ],
[ "Bob", "Berlin" ],
[ "Alice", "Aachen" ]</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(
  `"name","city"{ char('\n') }` ||
  `"Bob ""The Exemplar"" Mustermann","Berlin"{ char('\n') }`
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">(
  [ "name", "city" ],
  [ 'Bob "The Exemplar" Mustermann', "Berlin" ]
)</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Non-default record- and field-delimiters:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(
  "name;city§Bob;Berlin§Alice;Aachen", 
  { "row-delimiter": "§", "field-delimiter": ";" }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "name", "city" ],
[ "Bob", "Berlin" ],
[ "Alice", "Aachen" ]</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Non-default quote character:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(
  string-join(
    ("|name|,|city|", "|Bob|,|Berlin|"),
    char('\n')
  ), 
  { "quote-character": "|" }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "name", "city" ],
[ "Bob", "Berlin" ]</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Trimming whitespace in fields:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-arrays(
  string-join(
    ("name  ,city    ", "Bob   ,Berlin  ", "Alice ,Aachen  "),
    char('\n')
  ),
  { "trim-whitespace": true() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">[ "name", "city" ],
[ "Bob", "Berlin" ],
[ "Alice", "Aachen" ]</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="csv-to-xdm-mapping"><head>Enhanced parsing of CSV data to maps and arrays</head><p>While <function>fn:csv-to-arrays</function> simply delivers the CSV content
                  as a sequence of arrays, the <function>fn:parse-csv</function> function goes a step
                  further and enables access to the data using column names. The column
                  names may be taken either from the first row of the CSV data, or from
                  data supplied by the caller in the <code nobreak="false">options</code> parameter.</p></div3><div3 id="parsed-csv-structure-record"><head>Record fn:parsed-csv-structure-record</head><p>This record type is used to hold the result of the <function>fn:parse-csv</function> function.</p><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Name</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">columns</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
               <p>This entry holds a sequence of strings containing column names.
                  The content depends on the setting of the <code nobreak="false">header</code>
                  entry in <code nobreak="false">$options</code>:</p>
               
                  <ulist><item><p>With <code nobreak="false">"header":false()</code> (which is the default),
                     the value of this entry is the empty sequence.</p></item><item><p>With <code nobreak="false">"header":true()</code>, the value is a sequence
                     of strings taken from the first row of the data. The strings have
                     leading and trailing whitespace trimmed, regardless of the value of the
                     <code nobreak="false">trim-whitespace</code> option. The sequence
                     of strings will potentially be truncated if the <code nobreak="false">number-of-columns</code>
                     option is specified, and it will potentially be reordered if the
                     <code nobreak="false">filter-columns</code> option is specified. Any strings that are
                     zero-length or duplicated are retained <emph>as-is</emph>.</p></item><item><p>If the value of the <code nobreak="false">header</code> option is a sequence
                     of strings, then the value is taken from the supplied sequence.</p><p>The order of names is <emph>not</emph> adjusted based on the 
                        <code nobreak="false">select-columns</code> 
                        option; the supplied list of names is expected to refer to columns
                        in the result, not to columns in the input.</p></item></ulist>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:string*</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">column-index</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
         
         <p>This entry holds a map from column names (as strings) to
                  column positions (as 1-based positive integers).
                  The content depends on the setting of the <code nobreak="false">header</code>
                  entry in <code nobreak="false">$options</code>:</p>
               
               <ulist><item><p>With <code nobreak="false">"header":false()</code> (which is the default),
                     the value of this entry is the empty map.</p></item><item><p>With <code nobreak="false">"header":true()</code>, the map
                     contains entries based on the contents of the first row of the data. 
                     The strings have
                     leading and trailing whitespace trimmed, regardless of the value of the
                     <code nobreak="false">trim-whitespace</code> option. Any string appearing in the header
                     row that is non-zero-length and is not equal (using codepoint collation) to
                     any previous string appearing in the header results in an entry
                     pairing that string to its 1-based position in the header row.</p><p>If the <code nobreak="false">select-columns</code> 
                     option is present then the entries are adjusted (or removed) to
                     reflect their position in the adjusted data rows.</p></item><item><p>If the value of the <code nobreak="false">header</code> option is a 
                     sequence of strings, then the map contains entries based on the supplied value.
                     Any string appearing in the option value that is non-zero-length and 
                     is not equal (using codepoint collation) to
                     any previous string results in an entry
                     pairing that string to its 1-based position in the sequence.
                  </p><p>The allocation of column numbers is <emph>not</emph> adjusted based on the 
                        <code nobreak="false">select-columns</code> 
                        option; the supplied list of names is expected to refer to columns
                        in the result, not to columns in the input.</p></item></ulist>
         <ulist><item><p><term>Type: </term><code nobreak="false">map(xs:string,xs:integer)?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">rows</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>This entry is a sequence of arrays of strings, holding the parsed
                  rows of the CSV data. The format is the same as the result of the
                  <function>fn:csv-to-arrays</function> function, except that the first row
                  is omitted in the case where the <code nobreak="false">header</code>
                  option is <code nobreak="false">true</code>. If there are no data rows in the CSV, the
                  value will be the empty sequence.</p><ulist><item><p><term>Type: </term><code nobreak="false">array(xs:string)*</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">get</code></p></td><td class="fos-thin" rowspan="1" colspan="1"><p>A function providing ready access to a given field in a given
      row. The <code nobreak="false">get</code> function has signature:</p>
                     <eg xml:space="preserve">function($row as xs:positiveInteger, $column as (xs:positiveInteger | xs:string)) as xs:string</eg>
                     <p>The function takes two arguments: the first is an
                     integer giving the row number (1-based), the second
                     identifies a column either by its name or by its 1-based
                     position.</p>
         
         <p>Except in error cases (described below), 
                  the function call <code nobreak="false">$csv?get($R, $C)</code>, where <code nobreak="false">$C</code>
                  is an integer, returns the value of <code nobreak="false">$csv?rows[$R] =&gt; array:get($C, "")</code>,
                  and the function call <code nobreak="false">$csv?get($R, $K)</code>, where <code nobreak="false">$K</code>
                  is a string, returns the value of <code nobreak="false">$csv?get($R, $csv?column-index($K))</code>.</p>

               <p>The properties of the function are as follows:</p>
                  <glist><gitem><label>Name</label><def><p>Absent</p></def></gitem><gitem><label>Signature</label><def><p><code nobreak="false">(xs:positiveInteger, (xs:positiveInteger | xs:string)) =&gt; xs:string</code></p></def></gitem><gitem><label>Non-local variable bindings</label><def><p>None</p></def></gitem><gitem><label>Body</label><def><p>As described in the specification above</p></def></gitem><gitem><label>Errors</label><def><p>A dynamic error <errorref class="CV" code="0004"/> occurs if the
                           supplied <var>$key</var> is a string and does not occur in the map of column
                           names.</p></def></gitem><gitem><label>Rules</label><def><p>The function returns a field in the result.</p><p>The first argument <code nobreak="false">$row</code> selects a row within the sequence of rows
                              returned as <var>rows</var> by position (one-based). If the value is out of range for the number
                              of rows returned, the <code nobreak="false">get</code> function returns a zero-length
                              string.</p><p>The second argument <code nobreak="false">$col</code> may be either an integer or a string.</p><p>If <code nobreak="false">$col</code> is an integer then it selects a field within the
                              selected row by position (one-based). If the value is out of range for the number
                              of fields in the selected row, the <code nobreak="false">get</code> function returns a zero-length
                              string.</p><p>If <code nobreak="false">$col</code> is a string, the string is mapped to an integer using the
                              map in the returned <var>column-index</var>. If the string is not present
                              in this map, then an error is raised <errorref class="CV" code="0004"/>. The resulting
                              integer is then used as if it were supplied as <code nobreak="false">$col</code> directly.</p></def></gitem></glist>
         <ulist><item><p><term>Type: </term><code nobreak="false">function(xs:positiveInteger, (xs:positiveInteger | xs:string)) as xs:string</code></p></item></ulist></td></tr></tbody></table></div3><div3 id="func-parse-csv"><head>fn:parse-csv</head><changes><change PR="533 719 834 1066" issue="413 1052" date="2024-03-19">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Parses CSV data, returning the results in the form of a record containing information about the
            names in the header, as well as the data itself.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="parse-csv" return-type-ref="parsed-csv-structure-record" return-type-ref-occurs="?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>The input supplied in <code nobreak="false">$value</code> is CSV data, as defined
            in <bibref ref="rfc4180"/>. The function
            first parses the input using <function>fn:csv-to-arrays</function>, and then
            further processes the result. The initial parsing is exactly as defined for
            <function>fn:csv-to-arrays</function>, and can be controlled using the same options.
            Additional options are available to control the way in which header information and
            column names are handled.</p><p>If the input is the a zero-length string, the function
               returns a <code nobreak="false">parsed-csv-structure-record</code> whose 
               <code nobreak="false">rows</code> entry is the empty sequence.</p><p>The <code nobreak="false">$options</code> argument can be used to control the way in which the parsing
            takes place. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><p>The entries that may appear in the <code nobreak="false">$options</code> map are as follows:</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="field-delimiter" type="xs:string" occur="opt"/><arg name="row-delimiter" type="xs:string" occur="opt"/><arg name="quote-character" type="xs:string" occur="opt"/><arg name="trim-whitespace" type="xs:boolean" occur="opt"/><arg name="header" type="item()*" occur="opt"/><arg name="select-columns" type="xs:positiveInteger*" occur="opt"/><arg name="trim-rows" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">field-delimiter?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The character used to delimit fields within a record. An instance of
                  <code nobreak="false">xs:string</code> whose length is exactly one.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">","</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">row-delimiter?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The character used to delimit rows within
                  the CSV string. An instance of
                  <code nobreak="false">xs:string</code> whose length is exactly one.
                  Defaults to a single newline character (<char>U+000A</char>).
                  Note that this is tested after line endings are normalized.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">char('\n')</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">quote-character?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The character used to quote fields within the CSV string. An instance of
                  <code nobreak="false">xs:string</code> whose length is exactly one.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">'"'</code></p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">trim-whitespace?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether leading and trailing whitespace
                  is removed from the content of unquoted fields.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">Unquoted fields will be returned with any leading or trailing
                     whitespace intact.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">Unquoted fields will be returned with leading or trailing
                     whitespace removed, and all other whitespace preserved.
                  </td></tr><tr><td rowspan="4" colspan="1"><p><code nobreak="false">header?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether the first row of the CSV should be treated as a list
                  of column names, or whether column names are being supplied by the caller. 
                  The value must either be a single boolean, or a sequence of zero or more strings.
               <ulist><item><p><term>Type: </term><code nobreak="false">item()*</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">Column names are taken from the
                     first row of the CSV data.</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">Column names are not available; all references
                     to columns are by ordinal position.</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">xs:string*</code></td><td rowspan="1" colspan="1">Supplies explicit names for the columns. The <var>N</var>th
                     name in the list applies to the <var>N</var>th column after any filtering or rearrangement.
                     A zero-length string can be used when there is a column that requires no name.
                  </td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">select-columns?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">A sequence of integers indicating which columns to include and in which order. If this
                  option is absent or empty, all columns are returned in their original
                  order. For example, the value <code nobreak="false">1 to 4</code> indicates that the output
                  contains the first, second, third, and fourth columns from the input, in order,
                  while <code nobreak="false">(1, 5, 4)</code> indicates that the output
                  contains three columns, taken from the first, fifth, and fourth columns of the input,
                  in that order. An integer in the sequence is treated as the 1-based 
                  index of the column to include. Any other columns are dropped. 
                  If a particular row includes no field at the specified index,
                  the empty field is included at the relevant position in the result. If an integer appears
                  more than once then the result will include duplicated columns.
               <ulist><item><p><term>Type: </term><code nobreak="false">xs:positiveInteger*</code></p></item><item><p><term>Default: </term><code nobreak="false">()</code></p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">trim-rows?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Determines whether all rows should be adjusted to
                  contain the same number of fields. This option is ignored if
                  <code nobreak="false">select-columns</code> is specified.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">No padding or trimming of rows takes place,
                  unless requested using the <code nobreak="false">select-columns</code> option.</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The number of fields in the first row (whether this
                     be a header or a data row) determines the number of fields in every
                     subsequent row; to achieve this, excess fields are removed, or
                     additional zero-length fields are added.
                  </td></tr></tbody></table><p>The result of the function is a <code nobreak="false">parsed-csv-structure-record</code>, as
         defined in <specref ref="parsed-csv-structure-record"/>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error <errorref class="CV" code="0001"/> occurs if the value of
            <code nobreak="false">$csv</code> does not conform to the required grammar.</p><p>A dynamic error <errorref class="CV" code="0002"/> occurs if any of the
            options <code nobreak="false">field-delimiter</code>, <code nobreak="false">row-delimiter</code>, or <code nobreak="false">quote-character</code>
            is not a single character.</p><p>A dynamic error <errorref class="CV" code="0003"/> occurs if the same character is used
            for more than one of the options
            <code nobreak="false">field-delimiter</code>, <code nobreak="false">row-delimiter</code>, and
            <code nobreak="false">quote-character</code>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The default row delimiter is a single newline character <char>U+000A</char>. 
            Alternative line endings
         such as <code nobreak="false">CR</code> and <code nobreak="false">CRLF</code> will already have been normalized to a single
         newline.</p><p>All fields are returned as <code nobreak="false">xs:string</code> values.</p><p>Quoted fields in the input are returned without the quotes.</p><p>For more discussion of the returned data, see <specref ref="csv-to-xdm-mapping"/>.</p><p>If the source of the CSV input is a resource accessible by URI, then it may be preferable
         to use the <function>fn:csv-doc</function> function. If the source is a binary value (<code nobreak="false">xs:hexBinary</code>
         or <code nobreak="false">xs:base64Binary</code>) then this can first be decoded as a string using the functions
         <function>bin:infer-encoding</function> and <function>bin:decode-string</function>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $display := fn($result) {
  (: tidy up the result for display (function items cannot be properly displayed) :)         
  map:put($result, "get", "(: function :)")
}</eg></td></tr></tbody></table><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>Default delimiters, no column headers:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $input := string-join(
  ("name,city", "Bob,Berlin", "Alice,Aachen"),
  char('\n')
)
let $result := parse-csv($input)
return (
  $result =&gt; $display(),
  $result?get(1, 2),
  $result?get(2, 2)
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "columns": (),
  "column-index": {},
  "rows": ([ "name", "city" ], [ "Bob", "Berlin" ], [ "Alice", "Aachen" ]),
  "get": "(: function :)"
},
"city",
"Berlin"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Default delimiters, column headers:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $input := string-join(
  ("name,city", "Bob,Berlin", "Alice,Aachen"),
  char('\n')
)
let $result := parse-csv($input, { "header": true() })
return (
  $result =&gt; $display(),
  $result?get(1, "name"),
  $result?get(2, "city")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "columns": ("name", "city"),
  "column-index": { "name": 1, "city": 2 },
  "rows": ([ "Bob", "Berlin" ], [ "Alice", "Aachen" ]),
  "get": "(: function :)"
},
"Bob",
"Aachen"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Custom delimiters, no column headers:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $options := {
  "row-delimiter": "§", 
  "field-delimiter": ";", 
  "quote-character": "|"
}
let $input := "|name|;|city|§|Bob|;|Berlin|§|Alice|;|Aachen|"
let $result := parse-csv($input, $options)
return (
  $result =&gt; $display(),
  $result?get(3, 1)
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "columns": (),
  "column-index": {},
  "rows": ([ "name", "city" ], [ "Bob", "Berlin" ], [ "Alice", "Aachen" ]),
  "get": "(: function :)"
},
"Alice"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Supplied column names:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $headers := ("Person", "Location")
let $options := { "header": $headers, "row-delimiter": ";" }
let $input := "Alice,Aachen;Bob,Berlin;"
let $parsed-csv := parse-csv($input, $options)
return (
  $parsed-csv =&gt; $display(), 
  $parsed-csv?get(2, "Location")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "columns": ("Person", "Location"),
  "column-index": { "Person": 1, "Location": 2 },
  "rows": ([ "Alice", "Aachen" ], [ "Bob", "Berlin" ]),
  "get": "(: function :)"                  
},
"Berlin"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Filtering columns, with ragged input and <code nobreak="false">header: true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $input := string-join((
   "date,name,city,amount,currency,original amount,note",
   "2023-07-19,Bob,Berlin,10.00,USD,13.99",
   "2023-07-20,Alice,Aachen,15.00",
   "2023-07-20,Charlie,Celle,15.00,GBP,11.99,cake,not a lie"
), char('\n'))
let $options := { 
  "header": true(), 
  "select-columns": (2, 1, 4)
}
let $result := parse-csv($input, $options)
return (
  $result =&gt; $display(),
  $result?get(2, "amount")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "columns": ("name", "date", "amount"),
  "column-index": { "name": 1, "date": 2, "amount": 3 },
  "rows": (
    [ "Bob", "2023-07-19", "10.00" ],
    [ "Alice", "2023-07-20", "15.00" ],
    [ "Charlie", "2023-07-20", "15.00" ]
  ),
  "get": "(: function :)"                  
},
"15.00"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Filtering columns, with supplied column map</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $input := string-join((
  "2023-07-20,Alice,Aachen,15.00",                  
  "2023-07-19,Bob,Berlin,10.00,USD,13.99",
  "2023-07-20,Charlie,Celle,15.00,GBP,11.99,cake,not a lie"
), char('\n'))
let $options := { 
  "header": ( "Person", "", "Amount" ),
  "select-columns": (2, 1, 4)
}
let $result := parse-csv($input, $options)
return (
  $result =&gt; $display(),
  $result?get(2, "Person"),
  $result?get(2, "Amount")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "columns": ("Person", "", "Amount"),
  "column-index": { "Person": 1, "Amount": 3 },
  "rows": ([ "Alice", "2023-07-20", "15.00" ], 
           [ "Bob", "2023-07-19", "10.00" ], 
           [ "Charlie", "2023-07-20", "15.00" ]),
  "get": "(: function :)"                  
},
"Bob",
"10.00"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Specifying the number of columns explicitly, with <code nobreak="false">header: false()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $input := string-join((
  "date,      name,     amount,    currency,   original amount",               
  "2023-07-19,Bob,      10.00,     USD,        13.99",
  "2023-07-20,Alice,    15.00",
  "2023-07-20,Charlie,  15.00,     GBP,        11.99,             extra data"
), char('\n'))
let $options := {
  "header": false(), 
  "select-columns": 1 to 5, 
  "trim-whitespace" :true()
}
let $result := parse-csv($input, $options)
return (
  $result =&gt; $display(),
  $result?get(4, 3)
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "columns": (),
  "column-index": {},
  "rows": (
    [ "date", "name", "amount", "currency", "original amount" ],
    [ "2023-07-19", "Bob", "10.00", "USD", "13.99" ],
    [ "2023-07-20", "Alice", "15.00", "", "" ],
    [ "2023-07-20", "Charlie", "15.00", "GBP", "11.99" ]
  ),
  "get": "(: function :)"                  
},
"15.00"</eg></td></tr><tr><td colspan="2" rowspan="1"><p>Specifying the number of columns with a number and <code nobreak="false">header: true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $input := string-join((
  "date,name,city,amount,currency,original amount,note",               
  "2023-07-19,Bob,Berlin,10.00,USD,13.99",
  "2023-07-20,Alice,Aachen,15.00",
  "2023-07-20,Charlie,Celle,15.00,GBP,11.99,cake,not a lie"
), char('\n'))
let $options := { "header": true(), "select-columns": 1 to 6 }
let $result := parse-csv($input, $options)
return (
  $result =&gt; $display(),
  $result?get(3, "original amount")
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">{
  "columns": ("date", "name", "city", 
              "amount", "currency", "original amount"),
  "column-index": {
    "date": 1, "name": 2, "city": 3, "amount": 4,
    "currency": 5, "original amount": 6
  },
  "rows": (
    [ "2023-07-19", "Bob", "Berlin", "10.00", "USD", "13.99"],
    [ "2023-07-20", "Alice", "Aachen", "15.00", "", ""],
    [ "2023-07-20", "Charlie", "Celle", "15.00", "GBP", "11.99"]
  ),
  "get": "(: function :)"                  
},
"11.99"</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-csv-doc"><head>fn:csv-doc</head><changes><change issue="748" PR="2013" date="2025-05-20">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Reads an external resource containing CSV, and returns the results as a record
            containing information about the names in the header, as well as the data itself.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="csv-doc" return-type="fn:parsed-csv-structure-record?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="source" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The effect of the two-argument function call <code nobreak="false">fn:csv-doc($H, $M)</code> is
            equivalent to the function composition
            <code nobreak="false">fn:unparsed-binary($H) =&gt; fn:parse-csv($M)</code>.</p><p>If <code nobreak="false">$source</code> is the empty sequence, the function returns the empty sequence.</p><note><p>The ability to access external resources depends on whether the
         calling code is <xtermref spec="XP40" ref="dt-trusted"/>.</p></note></def></gitem><gitem><label>Error Conditions</label><def><p>The function may raise any error defined for the <function>fn:unparsed-text</function>
         or <function>fn:parse-csv</function> functions.</p></def></gitem></glist></div3><div3 id="csv-represent-as-xml"><head>Representing CSV data as XML</head><p>The <function>fn:csv-to-xml</function> function returns an XDM node tree representing the CSV data.
                  Following is a CSV text and the XML serialization of the corresponding node tree.</p><eg xml:space="preserve">Name,Date,Amount
Alice,2023-07-14,1.23
Bob,2023-07-14,2.34
               </eg><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;columns&gt;
    &lt;column&gt;Name&lt;/column&gt;
    &lt;column&gt;Date&lt;/column&gt;
    &lt;column&gt;Amount&lt;/column&gt;
  &lt;/columns&gt;
  &lt;rows&gt;
    &lt;row&gt;
      &lt;field column="Name"&gt;Alice&lt;/field&gt;
      &lt;field column="Date"&gt;2023-07-14&lt;/field&gt;
      &lt;field column="Amount"&gt;1.23&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="Name"&gt;Bob&lt;/field&gt;
      &lt;field column="Date"&gt;2023-07-14&lt;/field&gt;
      &lt;field column="Amount"&gt;2.34&lt;/field&gt;
    &lt;/row&gt;
  &lt;/rows&gt;
&lt;/csv&gt;
</eg><p>If no non-empty column names are available, then the <code nobreak="false">columns</code> 
                  element and all <code nobreak="false">column</code> attributes are absent. 
                  If non-empty column names are available for some columns but not for others,
                  then (a) the empty <code nobreak="false">column</code> element is included
                  within the <code nobreak="false">columns</code> element if and only if there is a subsequent
                  column with a non-empty name, and (b) the <code nobreak="false">column</code> attribute 
                  for the corresponding <code nobreak="false">field</code> elements is absent.</p><p>For example (when no column names are available):</p><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;rows&gt;
    &lt;row&gt;
      &lt;field&gt;Name&lt;/field&gt;
      &lt;field&gt;Date&lt;/field&gt;
      &lt;field&gt;Amount&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field&gt;Alice&lt;/field&gt;
      &lt;field&gt;2023-07-14&lt;/field&gt;
      &lt;field&gt;1.23&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field&gt;Bob&lt;/field&gt;
      &lt;field&gt;2023-07-14&lt;/field&gt;
      &lt;field&gt;2.34&lt;/field&gt;
    &lt;/row&gt;
  &lt;/rows&gt;
&lt;/csv&gt;
</eg><p>An XSD 1.0 schema for the XML representation is provided in 
                  <specref ref="schema-for-csv"/>.</p></div3><div3 id="func-csv-to-xml"><head>fn:csv-to-xml</head><changes><change PR="533 719 834 1066 1605" issue="413 1052" date="2023-07-25">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Parses CSV data supplied as a string, returning the results as an XML document, as described by
            <specref ref="csv-represent-as-xml"/>.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="csv-to-xml" return-type="document-node(fn:csv)?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:string?"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p>The arguments have the same meaning, and are subject to the same constraints, as
         the arguments of <function>fn:parse-csv</function>.</p><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the empty sequence.</p><p>In other cases, the effect of the function is equivalent to the result of the 
            following XQuery expression
            (where <code nobreak="false">$options</code> is the empty map if the argument is not supplied):</p><eg xml:space="preserve">let $parsedCSV := parse-csv($value, $options)
let $colNames := $parsedCSV?columns
return document {
   &lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt; {
     if (exists($colNames)) {
       &lt;columns&gt;{ $colNames ! &lt;column&gt;{ . }&lt;/column&gt; }&lt;/columns&gt;
     },
     &lt;rows&gt;{
       for $row in $parsedCSV?rows
       return &lt;row&gt;{
         for member $field at $col in $row
         return &lt;field&gt;{
           if ($colnames[$col]) {
             attribute column { $colnames[$col] }
           },
           $field
         }&lt;/field&gt;
       }&lt;/row&gt;
     }&lt;/rows&gt; 
   }&lt;/csv&gt; 
}</eg><p>The elements in the returned XML are in the namespace
            <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>;
            the namespace prefix that is used (or its absence) is 
            <termref def="implementation-dependent"/>.</p><p>If the function is called twice with the same arguments, it is <termref def="implementation-dependent"/> whether the two calls return the same element node
            or distinct (but deep equal) element nodes. In this respect it is <termref def="dt-nondeterministic">nondeterministic with respect to node identity</termref>.</p><p>The base URI of the element nodes in the result is <termref def="implementation-dependent"/>.</p><p>A schema is defined for the structure of the returned document: see <specref ref="schema-for-csv"/>.</p><p>The result of the function will always be such that validation against this schema would succeed.
            However, it is <termref def="implementation-defined"/> whether the result is typed or untyped,
            that is, whether the elements and attributes in the returned tree have type annotations that reflect
            the result of validating against this schema.</p></def></gitem><gitem><label>Error Conditions</label><def><p>See <function>fn:parse-csv</function>.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $crlf := char('\r') || char('\n')</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $csv-string := `name,city{ $crlf }Bob,Berlin{ $crlf }Alice,Aachen{ $crlf }`</eg></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $csv-uneven-cols := concat(
  `date,name,city,amount,currency,original amount,note{ $crlf }`,
  `2023-07-19,Bob,Berlin,10.00,USD,13.99{ $crlf }`,
  `2023-07-20,Alice,Aachen,15.00{ $crlf }`,
  `2023-07-20,Charlie,Celle,15.00,GBP,11.99,cake,not a lie{ $crlf }`
)</eg></td></tr></tbody></table><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>An empty CSV with default column extraction (false):</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml(())</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml("")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;rows/&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml(char('\n'))</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;rows&gt;
    &lt;row/&gt;
  &lt;/rows&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr><tr><td colspan="2" rowspan="1"><p>An empty CSV with header extraction:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml("", { "header": true() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;rows/&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr><tr><td colspan="2" rowspan="1"><p>An empty CSV with explicit column names:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml("", { "header": ("name", "", "city") })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;columns&gt;
    &lt;column&gt;name&lt;/column&gt;
    &lt;column/&gt;
    &lt;column&gt;city&lt;/column&gt;
  &lt;/columns&gt;
  &lt;rows/&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr><tr><td colspan="2" rowspan="1"><p>With defaults for delimiters and quotes, recognizing headers:</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml($csv-string, { "header": true() })</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;columns&gt;
    &lt;column&gt;name&lt;/column&gt;
    &lt;column&gt;city&lt;/column&gt;
  &lt;/columns&gt;
  &lt;rows&gt;
    &lt;row&gt;
      &lt;field column="name"&gt;Bob&lt;/field&gt;
      &lt;field column="city"&gt;Berlin&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="name"&gt;Alice&lt;/field&gt;
      &lt;field column="city"&gt;Aachen&lt;/field&gt;
    &lt;/row&gt;
  &lt;/rows&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr><tr><td colspan="2" rowspan="1"><p>Filtering columns</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml(
  $csv-uneven-cols, 
  { "header": true(), "select-columns": (2, 1, 4) }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;columns&gt;
    &lt;column&gt;name&lt;/column&gt;
    &lt;column&gt;date&lt;/column&gt;
    &lt;column&gt;amount&lt;/column&gt;
  &lt;/columns&gt;
  &lt;rows&gt;
    &lt;row&gt;
      &lt;field column="name"&gt;Bob&lt;/field&gt;
      &lt;field column="date"&gt;2023-07-19&lt;/field&gt;
      &lt;field column="amount"&gt;10.00&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="name"&gt;Alice&lt;/field&gt;
      &lt;field column="date"&gt;2023-07-20&lt;/field&gt;
      &lt;field column="amount"&gt;15.00&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="name"&gt;Charlie&lt;/field&gt;
      &lt;field column="date"&gt;2023-07-20&lt;/field&gt;
      &lt;field column="amount"&gt;15.00&lt;/field&gt;
    &lt;/row&gt;
  &lt;/rows&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr><tr><td colspan="2" rowspan="1"><p>Ragged rows</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml(
  $csv-uneven-cols, 
  { "header": true() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;columns&gt;
    &lt;column&gt;date&lt;/column&gt;
    &lt;column&gt;name&lt;/column&gt;
    &lt;column&gt;city&lt;/column&gt;
    &lt;column&gt;amount&lt;/column&gt;
    &lt;column&gt;currency&lt;/column&gt;
    &lt;column&gt;original amount&lt;/column&gt;
    &lt;column&gt;note&lt;/column&gt;
  &lt;/columns&gt;
  &lt;rows&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-19&lt;/field&gt;
      &lt;field column="name"&gt;Bob&lt;/field&gt;
      &lt;field column="city"&gt;Berlin&lt;/field&gt;
      &lt;field column="amount"&gt;10.00&lt;/field&gt;
      &lt;field column="currency"&gt;USD&lt;/field&gt;
      &lt;field column="original amount"&gt;13.99&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-20&lt;/field&gt;
      &lt;field column="name"&gt;Alice&lt;/field&gt;
      &lt;field column="city"&gt;Aachen&lt;/field&gt;
      &lt;field column="amount"&gt;15.00&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-20&lt;/field&gt;
      &lt;field column="name"&gt;Charlie&lt;/field&gt;
      &lt;field column="city"&gt;Celle&lt;/field&gt;
      &lt;field column="amount"&gt;15.00&lt;/field&gt;
      &lt;field column="currency"&gt;GBP&lt;/field&gt;
      &lt;field column="original amount"&gt;11.99&lt;/field&gt;
      &lt;field column="note"&gt;cake&lt;/field&gt;
      &lt;field&gt;not a lie&lt;/field&gt;
    &lt;/row&gt;
  &lt;/rows&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr><tr><td colspan="2" rowspan="1"><p>Trimming rows to constant width</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml(
  $csv-uneven-cols, 
  { "header": true(), "trim-rows": true() }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;columns&gt;
    &lt;column&gt;date&lt;/column&gt;
    &lt;column&gt;name&lt;/column&gt;
    &lt;column&gt;city&lt;/column&gt;
    &lt;column&gt;amount&lt;/column&gt;
    &lt;column&gt;currency&lt;/column&gt;
    &lt;column&gt;original amount&lt;/column&gt;
    &lt;column&gt;note&lt;/column&gt;
  &lt;/columns&gt;
  &lt;rows&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-19&lt;/field&gt;
      &lt;field column="name"&gt;Bob&lt;/field&gt;
      &lt;field column="city"&gt;Berlin&lt;/field&gt;
      &lt;field column="amount"&gt;10.00&lt;/field&gt;
      &lt;field column="currency"&gt;USD&lt;/field&gt;
      &lt;field column="original amount"&gt;13.99&lt;/field&gt;
      &lt;field column="note"/&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-20&lt;/field&gt;
      &lt;field column="name"&gt;Alice&lt;/field&gt;
      &lt;field column="city"&gt;Aachen&lt;/field&gt;
      &lt;field column="amount"&gt;15.00&lt;/field&gt;
      &lt;field column="currency"/&gt;
      &lt;field column="original amount"/&gt;
      &lt;field column="note"/&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-20&lt;/field&gt;
      &lt;field column="name"&gt;Charlie&lt;/field&gt;
      &lt;field column="city"&gt;Celle&lt;/field&gt;
      &lt;field column="amount"&gt;15.00&lt;/field&gt;
      &lt;field column="currency"&gt;GBP&lt;/field&gt;
      &lt;field column="original amount"&gt;11.99&lt;/field&gt;
      &lt;field column="note"&gt;cake&lt;/field&gt;
    &lt;/row&gt;
  &lt;/rows&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr><tr><td colspan="2" rowspan="1"><p>Specifying a fixed number of columns</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">csv-to-xml(
  $csv-uneven-cols, 
  { "header": true(), "select-columns": 1 to 6 }
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
&lt;csv xmlns="http://www.w3.org/2005/xpath-functions"&gt;
  &lt;columns&gt;
    &lt;column&gt;date&lt;/column&gt;
    &lt;column&gt;name&lt;/column&gt;
    &lt;column&gt;city&lt;/column&gt;
    &lt;column&gt;amount&lt;/column&gt;
    &lt;column&gt;currency&lt;/column&gt;
    &lt;column&gt;original amount&lt;/column&gt;
  &lt;/columns&gt;
  &lt;rows&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-19&lt;/field&gt;
      &lt;field column="name"&gt;Bob&lt;/field&gt;
      &lt;field column="city"&gt;Berlin&lt;/field&gt;
      &lt;field column="amount"&gt;10.00&lt;/field&gt;
      &lt;field column="currency"&gt;USD&lt;/field&gt;
      &lt;field column="original amount"&gt;13.99&lt;/field&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-20&lt;/field&gt;
      &lt;field column="name"&gt;Alice&lt;/field&gt;
      &lt;field column="city"&gt;Aachen&lt;/field&gt;
      &lt;field column="amount"&gt;15.00&lt;/field&gt;
      &lt;field column="currency"/&gt;
      &lt;field column="original amount"/&gt;
    &lt;/row&gt;
    &lt;row&gt;
      &lt;field column="date"&gt;2023-07-20&lt;/field&gt;
      &lt;field column="name"&gt;Charlie&lt;/field&gt;
      &lt;field column="city"&gt;Celle&lt;/field&gt;
      &lt;field column="amount"&gt;15.00&lt;/field&gt;
      &lt;field column="currency"&gt;GBP&lt;/field&gt;
      &lt;field column="original amount"&gt;11.99&lt;/field&gt;
    &lt;/row&gt;
  &lt;/rows&gt;
&lt;/csv&gt;
</eg><p>(with whitespace added for legibility)</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="illustrative-csv-examples"><head>Illustrative examples of processing CSV data</head><p>The following examples illustrate more complex applications making use of CSV parsing functions.</p><p>A variable <code nobreak="false">$crlf</code> is assumed to be in scope representing the CRLF string:</p><eg xml:space="preserve">let $crlf := fn:char(0x0D)||fn:char(0x0A)</eg><example id="csv-to-html-table"><head>Converting a CSV into an HTML-style table using <function>fn:parse-csv</function></head><p>Direct conversion is a matter of iterating across the records and fields to
                     generate <code nobreak="false">&lt;tr&gt;</code> and <code nobreak="false">&lt;td&gt;</code> elements.</p><p>Using XQuery:</p><eg xml:space="preserve">
let $csv := fn:parse-csv(`name,city{ $crlf }Bob,Berlin`)
return &lt;table&gt;
  &lt;thead&gt;{
    for $column in $csv?columns?fields
    return &lt;th&gt;{ $column }&lt;/th&gt;
  }&lt;/thead&gt;
  &lt;tbody&gt;{
    for $row in $csv?rows
    return &lt;tr&gt;{ for $field in $row?fields return &lt;td&gt;{ $field }&lt;/td&gt; }&lt;/tr&gt;
  }&lt;/tbody&gt;
&lt;/table&gt;</eg><p>Using XSLT:</p><eg xml:space="preserve">
&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:eg="http://example.org/eg"
  xmlns:array="http://www.w3.org/2005/xpath-functions/array"
  exclude-result-prefixes="eg array"
  version="4.0"&gt;
  &lt;xsl:output method="xml" indent="true"/&gt;

  &lt;xsl:template match="." mode="csv-th" expand-text="true"&gt;
    &lt;th&gt;{ . }&lt;/th&gt;
  &lt;/xsl:template&gt;

  &lt;xsl:template match="." mode="csv-td" expand-text="true"&gt;
    &lt;td&gt;{ . }&lt;/td&gt;
  &lt;/xsl:template&gt;

  &lt;xsl:template match="." mode="csv-tr"&gt;
    &lt;tr&gt;
      &lt;xsl:apply-templates select=".?fields" mode="csv-td"/&gt;
    &lt;/tr&gt;
  &lt;/xsl:function&gt;

  &lt;xsl:template name="xsl:initial-template"&gt;
    &lt;xsl:variable name="csv" select="parse-csv(`name,city{ $crlf }Bob,Berlin`)"/&gt;
    &lt;table&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;xsl:apply-templates select="$csv?columns?fields" mode="csv-th"/&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;xsl:apply-templates select="$csv?rows" mode="csv-tr"/&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
                  </eg></example><example id="csv-to-html-table-csv-to-xml"><head>Converting a CSV into an HTML-style table using <function>fn:csv-to-xml</function></head><p>The <function>fn:csv-to-xml</function> function makes these kinds of
                     conversion-to-XML-table tasks simpler by providing a simple XML represenation of the data. Here, in XQuery:</p><eg xml:space="preserve">
let $csv := csv-to-xml(`name,city{ $crlf }Bob,Berlin`)
return &lt;table&gt;
  &lt;thead&gt;{
    for $column in $csv/csv/columns/column
    return &lt;th&gt;{ $column }&lt;/th&gt;
  }&lt;/thead&gt;
  &lt;tbody&gt;{
    for $row in $csv/csv/rows/row
    return &lt;tr&gt;{ for $field in $row/field return &lt;td&gt;{ $field }&lt;/td&gt; }&lt;/tr&gt;
  }&lt;/tbody&gt;
&lt;/table&gt;
                  </eg><p>And in XSLT:</p><eg xml:space="preserve">
&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fn="http://www.w3.org/2005/xpath-functions"
  exclude-result-prefixes="fn"
  version="4.0"&gt;
  &lt;xsl:output method="xml" indent="true"/&gt;

  &lt;xsl:template match="fn:column" expand-text="true"&gt;
    &lt;th&gt;{ . }&lt;/th&gt;
  &lt;/xsl:template&gt;

  &lt;xsl:template match="fn:field" expand-text="true"&gt;
    &lt;td&gt;{ . }&lt;/td&gt;
  &lt;/xsl:template&gt;

  &lt;xsl:template match="fn:row"&gt;
    &lt;tr&gt;
      &lt;xsl:apply-templates/&gt;
    &lt;/tr&gt;
  &lt;/xsl:function&gt;

  &lt;xsl:template match="fn:columns"&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
  &lt;/xsl:function&gt;

  &lt;xsl:template match="fn:rows"&gt;
    &lt;tbody&gt;
      &lt;xsl:apply-templates/&gt;
    &lt;/tbody&gt;
  &lt;/xsl:function&gt;

  &lt;xsl:template match="fn:csv"&gt;
    &lt;table&gt;
      &lt;xsl:apply-templates/&gt;
    &lt;/table&gt;
  &lt;/xsl:template&gt;

  &lt;xsl:template name="xsl:initial-template"&gt;
    &lt;xsl:apply-templates select="fn:csv-to-xml(`name,city{ $crlf }Bob,Berlin`)"/&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
                  </eg></example></div3></div2><div2 id="ixml-functions"><head>Functions on Invisible XML</head><p>This section describes functions that support
            <bibref ref="invisible-xml"/> parsing.</p><p>Invisible XML defines a BNF-like language for specifying grammars, together with 
            a mapping from sentences in that grammar to an XML representation. By defining an
            Invisible XML grammar, a great variety of non-XML data formats can be manipulated
            as if they were XML. The function <function>fn:invisible-xml</function> takes a grammar
            as input, and returns a function which can be used for parsing data instances
            and converting them to XML node trees.</p><div3 id="func-invisible-xml"><head>fn:invisible-xml</head><changes><change issue="238 991 1281 1404" PR="791 1256 1282 1405">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Creates an Invisible XML parser for a grammar.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="invisible-xml" return-type="fn(xs:string) as item()" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="grammar" type="(xs:string | element(Q{}ixml))?" default="()"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Conceptually, an <bibref ref="invisible-xml"/> processor
         takes two arguments: a grammar and an input string. The grammar
         is a description of some format and the parser will attempt to
         interpret the input string according to that description. The parser
         returns an XML representation of the input string as parsed
         by the provided grammar. If parsing fails, it returns an XML
         representation that indicates an error occurred and may
         provide additional error information.</p><p>If the function is called twice with the same arguments, it is 
         <termref def="dt-nondeterministic">nondeterministic with respect to node identity</termref>.
         </p><p>For example, the following grammar describes a date as consisting
         of a year, a month, and a day. Each are a sequence of digits and they are
         separated by hyphens:</p><eg xml:space="preserve"> date = year, -'-', month, -'-', day .
 year = d, d, d, d .
month = '0', d | '1', ['0'|'1'|'2'] .
  day = ['0'|'1'|'2'], d | '3', ['0'|'1'] .
   -d = ['0'-'9'] .</eg><p>Using this grammar to parse “2023-10-31” will produce:</p><eg xml:space="preserve">&lt;date&gt;&lt;year&gt;2023&lt;/year&gt;&lt;month&gt;10&lt;/month&gt;&lt;day&gt;31&lt;/day&gt;&lt;/date&gt;</eg><p>Using this grammar to parse “2023-10-32” will produce something like this:</p><eg xml:space="preserve">&lt;fail xmlns:ixml='http://invisiblexml.org/NS' ixml:state='failed'&gt;
  &lt;line&gt;1&lt;/line&gt;
  &lt;column&gt;10&lt;/column&gt;
  &lt;pos&gt;9&lt;/pos&gt;
  &lt;unexpected&gt;3&lt;/unexpected&gt;
  &lt;permitted&gt;'3', ['0'; '1'; '2']&lt;/permitted&gt;
&lt;/fail&gt;</eg><p>The exact format of the error output will vary between implementations.
         The only required part of the output is the <code nobreak="false">ixml:state</code> attribute
         that contains the value <code nobreak="false">failed</code>.</p><note><p>Careful readers will observe that the example grammar
         will parse “2023-00-00” as a date. The grammar could easily be extended to
         exclude the “00” forms for month and day, but this is only intended to be
         an illustrative example.</p></note><p>The <function>fn:invisible-xml</function> function takes a grammar and
         returns a function that can be used to parse input strings. In practice,
         constructing a parser from a grammar may be an expensive operation.
         Returning a parsing function makes it easy to efficiently reuse
         a parser.</p><p>The provided grammar must be a string conforming to the Invisible XML
         specification grammar or an XML representation of such a grammar.</p><p>The following options are available. The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="fail-on-error" type="xs:boolean" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">fail-on-error?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">Raise an error if the parse function fails<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr></tbody></table><p>Additional, <termref def="implementation-defined">implementation-defined</termref> options may be available, for example, to control
         aspects of the XML serialization, to specify the grammar start symbol,
         or to produce output formats other than XML.</p><p>If <code nobreak="false">$grammar</code> is the empty sequence, a parser is returned
         for the Invisible XML specification grammar. This <rfc2119>should</rfc2119> be the same
         grammar that the implementation uses to parse iXML grammars. If <code nobreak="false">$grammar</code> is not
         empty, it <rfc2119>must</rfc2119> be a valid Invisible XML grammar.
         If it is not, <function>fn:invisible-xml</function> raises
         <code nobreak="false">err:FOIX0001</code>.</p><p>The parsing function that is returned behaves as follows:</p><olist><item><p>It takes a string as input and returns an item as its result, usually an
            XML document containing the result of the parse. (The return type is <code nobreak="false">item()</code>
            to allow implementations to provide other sorts of results.)</p></item><item><p>It is <termref def="dt-nondeterministic">nondeterministic with respect to node identity</termref> (that
            is, if it is called twice with the same input string, it may or may not return the same
            document node each time).</p></item></olist><p>If the <code nobreak="false">fail-on-error</code> option is
         <code nobreak="false">true</code>, the parsing function will raise
         <code nobreak="false">err:FOIX0002</code> if the input provided cannot be
         parsed successfully. Otherwise, it returns an XML representation of the
         error (rooted at a document node) as described by the <bibref ref="invisible-xml"/> 
         specification.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">invisible-xml("S=A. A='a'.")("a")</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">&lt;S&gt;&lt;A&gt;a&lt;/A&gt;&lt;/S&gt;</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $parser := invisible-xml("S=A. A='a'.")
let $result := $parser("b")
return $result/*/@*:state = 'failed'</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">true()</eg><p><emph>(The returned document contains information about the error in the parsed string.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">
let $parser := invisible-xml("S=A. A='a'.", { "fail-on-error": true() })
let $result := $parser("b")
return $result
</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Raises error FOIX0002.</p></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="dynamic-loading"><head>Dynamic evaluation</head><p>The following functions allow dynamic loading and evaluation of XQuery queries, XSLT stylesheets,
               and XPath binary operators.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:load-xquery-module</code></td><td rowspan="1" colspan="1">Provides access to the public functions and global variables of a dynamically loaded XQuery library module.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:transform</code></td><td rowspan="1" colspan="1">Invokes a transformation using a dynamically loaded XSLT stylesheet.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:op</code></td><td rowspan="1" colspan="1">Returns a function whose effect is to apply a supplied binary operator to two arguments.</td></tr></tbody></table><div2 id="load-xquery-module-record"><head>Record fn:load-xquery-module-record</head><p>This record type is used to hold the result of the <function>fn:load-xquery-module</function> function.</p><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Name</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">variables</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
                   global variable declared in the library module. The key of the
                 <p>This map (<var>V</var> ) contains one entry for each public
                  entry is the name of the variable, as an <code nobreak="false">xs:QName</code>
                  value; the associated value is the value of the variable.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, item()*)</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">functions</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>This map (<var>F</var> ) contains one entry for each distinct QName
            <var>Q</var> that represents the name of a public and non-external
            function declared in the library module. The key of the entry is
            <var>Q</var>, as an <code nobreak="false">xs:QName</code> value; the associated value
            is a map <var>A</var>. This map (<var>A</var>) contains one entry for
            each arity <var>N</var> within the arity range of any of the function
            declarations with the given name; its key is <var>N</var>, as an
            <code nobreak="false">xs:integer</code> value, and its associated value is a function
            item obtained as if by evaluating a named function reference
            <code nobreak="false">Q#N</code>, using the static and dynamic context of the call on
            <function>fn:load-xquery-module</function>. The function item can be invoked
            using the rules for dynamic function invocation.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, map(xs:integer, function(*)))</code></p></item></ulist></td></tr></tbody></table></div2><div2 id="func-load-xquery-module"><head>fn:load-xquery-module</head><changes><change issue="725" PR="727" date="2023-10-10">It has been clarified that loading a module has no effect on the static or dynamic context
               of the caller.</change><change issue="883" PR="1072" date="2024-03-19">The return type is now specified more precisely.</change><change issue="1329" PR="1333" date="2024-07-22">A new option is provided to allow the content of the loaded module to be supplied as a string.</change></changes><glist><gitem><label>Summary</label><def><p>Provides access to the public functions and global variables of a dynamically loaded XQuery library module.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="load-xquery-module" return-type-ref="load-xquery-module-record" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="module-uri" type="xs:string"/><arg name="options" type="map(*)?" default="{}" note="default-on-empty"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function loads an implementation-defined set of modules having the target namespace <code nobreak="false">$module-uri</code>.</p><p>The <code nobreak="false">$options</code> argument can be used to control the way in which the function operates. 
            The <termref def="option-parameter-conventions">option parameter conventions</termref> apply.</p><p>If the query module is retrieved as an external resource, this is subject to
         the <xtermref spec="XP40" ref="dt-trusted">trust level</xtermref> of the
         calling code. In addition, the ability of the loaded query module to access
         additional resources is subject to the value of the supplied <code nobreak="false">trusted</code>
         option.</p><note><p>Versions of XQuery prior to 4.0 do not define any constraints on access to
            external resources. Many XQuery implementations, however, provide such
            mechanisms. An implementation of <code nobreak="false">fn:load-xquery-module</code> that allows
            execution of an <xtermref spec="XP40" ref="dt-untrusted">untrusted</xtermref>
            query <rfc2119>must</rfc2119> ensure that the ability of that query to access resources
            is appropriately restricted, regardless of the version of XQuery in use.</p></note><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="xquery-version" type="xs:decimal" occur="opt"/><arg name="trusted" type="xs:boolean" occur="opt"/><arg name="location-hints" type="xs:string*" occur="opt"/><arg name="content" type="xs:string?" occur="opt"/><arg name="context-item" type="item()?" occur="opt"/><arg name="variables" type="map(xs:QName, item()*)" occur="opt"/><arg name="vendor-options" type="map(xs:QName, item()*)" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">xquery-version?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The minimum level of the XQuery language that the
                  processor must support. <ulist><item><p><term>Type: </term><code nobreak="false">xs:decimal</code></p></item><item><p><term>Default: </term>The version given in the prolog of the library module; or
                  <termref def="implementation-defined">implementation-defined</termref> if this is absent.</p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">trusted?</code></p></td><td class="fos-thick" colspan="2" rowspan="1">Indicates whether the returned query module is 
                  trusted to access external resources. This applies both to resources
               statically referenced in the query module (such as imported schemas and
               imported library modules), and to resources accessed dynamically by
               invoking functions in the retrieved module, for example by use of the
               <function>fn:doc</function> function.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false()</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The loaded query has the same level of trust
                     as the caller, and may therefore access all external resources
                     available to the caller.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">The functions and variables in the returned
                     XQuery module are <xtermref spec="XP40" ref="dt-untrusted">untrusted</xtermref>, and
                     are therefore unable to access external resources unless these have been made
                     explicitly available by a trusted caller.
                  </td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">location-hints?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">A sequence of URIs (in the form of <code nobreak="false">xs:string</code> values) which may be used or ignored in an
                  <termref def="implementation-defined">implementation-defined</termref> way.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string*</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty sequence</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">content?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The content of the query module as a string. When this option is used, the 
                  <code nobreak="false">location-hints</code> option is ignored. The static base URI of the dynamically loaded
                  module is the same as the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> 
                  of the caller.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string?</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty sequence</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">context-item?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">The item to be used as the initial context item when evaluating global variables in the library module. Supplying
                  the empty sequence is equivalent to omitting the entry from the map, and indicates the absence of a context item.
                  If the library module specifies a required type for the context item, then the supplied value <rfc2119>must</rfc2119> conform to
                  this type, without conversion.<ulist><item><p><term>Type: </term><code nobreak="false">item()?</code></p></item><item><p><term>Default: </term><code nobreak="false">Absent</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">variables?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">Values for external variables defined in the library module. Values <rfc2119>must</rfc2119> be supplied
                  for external variables that have no default value, and <rfc2119>may</rfc2119> be supplied for external variables
                  that do have a default value. The supplied value <rfc2119>must</rfc2119> conform to the required type of the variable, without conversion.
                  The map contains one entry for each external variable: the key is the variable’s name, and the associated value is
                  the variable’s value. The <termref def="option-parameter-conventions">option parameter conventions</termref> do not apply
                  to this contained map.<ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, item()*)</code></p></item><item><p><term>Default: </term><code nobreak="false">The empty map</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">vendor-options?</code></p></td><td class="fos-thin" colspan="2" rowspan="1">Values for vendor-defined configuration options for the XQuery processor used to process the request. The key is the
                  name of an option, expressed as a QName: the namespace URI of the QName <rfc2119>should</rfc2119> be a URI controlled
                  by the vendor of the XQuery processor. The meaning of the associated value is <termref def="implementation-defined">implementation-defined</termref>.
                  Implementations <rfc2119>should</rfc2119> ignore options whose names are in an unrecognized namespace. 
                  The <termref def="option-parameter-conventions">option parameter conventions</termref> do not apply
                  to this contained map.<ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, item()*)</code></p></item><item><p><term>Default: </term><code nobreak="false">The empty map</code></p></item></ulist></td></tr></tbody></table><p>The result of the function is a map
         <var>R</var> with two entries, as defined in <specref ref="load-xquery-module-record"/>.</p><p>The static and dynamic context of the library module are established according to the rules in 
            <xspecref spec="XQ31" ref="id-xq-context-components"/>.</p><p>It is <termref def="implementation-defined">implementation-defined</termref> whether constructs in the library module 
            are evaluated in the same <termref def="execution-scope">execution scope</termref> as the calling module.</p><p>The library module that is loaded may import other modules using an <code nobreak="false">import module</code> declaration. The result of
            <function>fn:load-xquery-module</function> does not include global variables or functions declared in such a transitively imported module.
            However, the <code nobreak="false">options</code> map supplied in the function call <rfc2119>may</rfc2119> 
            (and if no default is defined, <rfc2119>must</rfc2119>)
            supply values for external variables declared in transitively loaded library modules.</p><p>The library module that is loaded may import schema declarations using an <code nobreak="false">import schema</code> declaration. It is
            <termref def="implementation-defined">implementation-defined</termref> whether schema components in the in-scope 
            schema definitions of the calling module
            are automatically added to the in-scope schema definitions of the dynamically loaded module. The in-scope schema definitions
            of the calling and called modules must be consistent, according to the rules defined in 
            <xspecref spec="XQ31" ref="id-consistency-constraints"/>.</p><p>Where nodes are passed to or from the dynamically loaded module, for example as an argument or result of a function, 
            they <rfc2119>should</rfc2119> if possible retain their node identity, their base URI, their type annotations, and their relationships to all other nodes 
            in the containing tree (including ancestors and siblings). If this is not possible, for example because the only way of passing nodes 
            to the chosen XQuery implementation is by serializing and re-parsing, then a node <rfc2119>may</rfc2119> be passed in the form of a deep 
            copy, which may lose information about the identity of the node, about its ancestors and siblings, about its base URI, about its type annotations, and about its 
            relationships to other nodes passed across the interface.</p></def></gitem><gitem><label>Error Conditions</label><def><p>If <code nobreak="false">$module-uri</code> is a zero length string, a dynamic error is raised <errorref class="QM" code="0001"/>.</p><p>If the implementation is not able to find a library module with the specified target namespace, 
            an error is raised <errorref class="QM" code="0002"/>.</p><p>If a static error (including a statically detected type error) is encountered when processing the library module, 
            a dynamic error is raised <errorref class="QM" code="0003"/>.</p><p>If a value is supplied for the initial context item or for an external variable and the value does not conform to the required
            type declared in the dynamically loaded module, a dynamic error is raised <errorref class="QM" code="0005"/>.</p><p>If no suitable XQuery processor is available, a dynamic error is raised <errorref class="QM" code="0006"/>.
         This includes (but is not limited to) the following cases:</p><olist><item><p>No XQuery processor is available;</p></item><item><p>Use of the function has been disabled;</p></item><item><p>No XQuery processor supporting the requested version of XQuery is available;</p></item><item><p>No XQuery processor supporting the optional Module Feature is available.</p></item></olist><p>If a dynamic error (including a dynamically detected type error) is encountered when processing the module 
            (for example, when evaluating its global variables), the dynamic error is returned <emph>as is</emph>.</p></def></gitem><gitem><label>Notes</label><def><note><p>If a function declaration <var>F</var> in the loaded module declares (say) four parameters of which one is optional,
            its arity range will be from 3 to 4, so the result will include two function items corresponding to <code nobreak="false">F#3</code>
            and <code nobreak="false">F#4</code>. In the lower-arity function item, <code nobreak="false">F#3</code>, the fourth parameter will take its
            default value. If the expression that initializes the default value is context sensitive, the static and dynamic
            context for its evaluation are the static and dynamic contexts of the <function>fn:load-xquery-module</function>
            function call itself.
         </p><p>As with all other functions in this specification, conformance requirements depend on the host language.
         For example, a host language might specify that provision of this function is optional, or that it is excluded entirely,
         or that implementations are required to support XQuery modules using a specified version of XQuery.</p><p>Even where support for this function is mandatory, it is <rfc2119>recommended</rfc2119> for security reasons that implementations
         should provide a user option to disable its use, or to disable aspects of its functionality.</p><p diff="add" at="issue725">The <code nobreak="false">load-xquery-module</code> function does not modify the static or dynamic context.
         Functions and variables from the loaded module become available within the result returned by the function, but they
         are not added to the static or dynamic context of the caller. This means, for example, that <code nobreak="false">function-lookup</code>
         will not locate functions from the loaded module.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $expr := "2 + 2"
let $module := `
  xquery version "4.0"; 
  module namespace dyn="http://example.com/dyn";
  declare %public variable $dyn:value := { $expr };
`
let $exec := load-xquery-module(
  "http://example.com/dyn",
  { 'content':$module }
)
let $variables := $exec?variables
return $variables( #Q{http://example.com/dyn}value )</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">4</eg></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-transform"><head>fn:transform</head><glist><gitem><label>Summary</label><def><p>Invokes a transformation using a dynamically loaded XSLT stylesheet.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="transform" return-type="map(*)" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="options" type="map(*)"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>This function loads an XSLT stylesheet and invokes it to perform a transformation.</p><p>The inputs to the transformation are supplied in the form of a map. 
            The <termref def="option-parameter-conventions">option parameter conventions</termref> apply
            to this map; they do not apply to any nested map unless otherwise specified.</p><p>The function first identifies the <term>requested XSLT version</term>, as follows:</p><ulist><item><p>If the <code nobreak="false">xslt-version</code>
               option is present, the requested XSLT version is the value of that option. </p></item><item><p>Otherwise, the requested XSLT version
               is the value of the <code nobreak="false">[xsl:]version</code> attribute of the outermost element in the supplied stylesheet or package.</p></item></ulist><p>The function then attempts to locate an XSLT processor that implements the requested XSLT version.</p><ulist><item><p>If a processor that implements the requested XSLT version is available, then it is used. </p></item><item><p>Otherwise, if a processor that implements a version later than the requested version is available, then it is used. </p></item><item><p>Otherwise, the function fails indicating that no suitable XSLT processor is available.</p></item></ulist><note><p>The phrase <emph>locate an XSLT processor</emph> includes the possibility of locating a software product and
         configuring it to act as an XSLT processor that implements the requested XSLT version.</p></note><p>If more than one XSLT processor is available under the above rules, then the one that is chosen may be selected according to
         the availability of requested features: see below.</p><p>Once an XSLT processor has been selected that implements a given version of XSLT, the processor
         follows the rules of that version of the XSLT specification. This includes any decision to operate in backwards or forwards
         compatibility mode. For example, if an XSLT 2.0 processor is selected, and the stylesheet specifies <code nobreak="false">version="1.0"</code>,
         then the processor will operate in backwards compatibility mode; if the same processor is selected and the stylesheet
         specifies <code nobreak="false">version="3.0"</code>, the processor will operate in forwards compatibility mode.</p><p>If the stylesheet to be executed is retrieved as an external resource, this is subject to
         the <xtermref spec="XP40" ref="dt-trusted">trust level</xtermref> of the
         calling code. In addition, the ability of the loaded stylesheet to access
         additional resources is subject to the value of the supplied <code nobreak="false">trusted</code>
         option.</p><note><p>Versions of XSLT prior to 4.0 do not define any constraints on access to
            external resources. Many XSLT implementations, however, provide such
            mechanisms. An implementation of <code nobreak="false">fn:transform</code> that allows
            an XSLT processor to execute an <xtermref spec="XP40" ref="dt-untrusted">untrusted</xtermref>
            stylesheet <rfc2119>must</rfc2119> ensure that the ability of that stylesheet to access resources
            is appropriately restricted, regardless of the version of XSLT.</p></note><p>The combinations of options that are relevant to each version of XSLT, other than <code nobreak="false">xslt-version</code> 
            itself, are listed below. This is followed by a table giving the meaning of each option.</p><olist><item><p>For invocation of an XSLT 1.0 processor (see <bibref ref="xslt10"/>), 
                  the supplied options must include all of the following <phrase diff="chg" at="E">(if anything else is present, it is ignored)</phrase>:</p><olist><item><p>The stylesheet, provided by supplying exactly one of the following:</p><slist><sitem>
                           <code nobreak="false">stylesheet-location</code>
                        </sitem><sitem>
                           <code nobreak="false">stylesheet-node</code>
                        </sitem><sitem>
                           <code nobreak="false">stylesheet-text</code>
                        </sitem></slist></item><item><p>The source tree, provided as the value of the <code nobreak="false">source-node</code> option.</p></item><item><p>Zero or more of the following additional options:</p><slist><sitem>
                           <code nobreak="false">stylesheet-base-uri</code>
                        </sitem><sitem><code nobreak="false">stylesheet-params</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">initial-mode</code> (defaults to the stylesheet’s default mode)</sitem><sitem><code nobreak="false">delivery-format</code> (defaults to <code nobreak="false">document</code>)</sitem><sitem><code nobreak="false">serialization-params</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">enable-messages</code> (default is implementation-defined)</sitem><sitem><code nobreak="false">requested-properties</code> (default is the empty map)</sitem><sitem><code nobreak="false">trusted</code> (default is <code nobreak="false">false</code>)</sitem><sitem><code nobreak="false">vendor-options</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">cache</code> (default is implementation-defined)</sitem></slist></item></olist></item><item><p>For invocation of an XSLT 2.0 processor (see <bibref ref="xslt20"/>), 
                  the supplied options must include all of the following <phrase diff="chg" at="E">(if anything else is present, it is ignored)</phrase>:</p><olist><item><p>The stylesheet, provided by supplying exactly one of the following:</p><slist><sitem>
                           <code nobreak="false">stylesheet-location</code>
                        </sitem><sitem>
                           <code nobreak="false">stylesheet-node</code>
                        </sitem><sitem>
                           <code nobreak="false">stylesheet-text</code>
                        </sitem></slist></item><item><p>Invocation details, as exactly one of the following:</p><olist><item><p>For apply-templates invocation, all of the following:</p><p>
                              <code nobreak="false">source-node</code>
                           </p><p>Optionally, <code nobreak="false">initial-mode</code> (defaults to the stylesheet’s default mode)</p></item><item><p>For call-template invocation, all of the following:</p><p>
                              <code nobreak="false">initial-template</code>
                           </p><p>Optionally, <code nobreak="false">source-node</code></p></item></olist></item><item><p>Zero or more of the following additional options:</p><slist><sitem>
                           <code nobreak="false">stylesheet-base-uri</code>
                        </sitem><sitem><code nobreak="false">stylesheet-params</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">base-output-uri</code> (defaults to absent)</sitem><sitem><code nobreak="false">delivery-format</code> (defaults to <code nobreak="false">document</code>)</sitem><sitem><code nobreak="false">serialization-params</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">enable-messages</code> (default is implementation-defined)</sitem><sitem><code nobreak="false">enable-trace</code> (default is implementation-defined)</sitem><sitem><code nobreak="false">requested-properties</code> (default is the empty map)</sitem><sitem><code nobreak="false">trusted</code> (default is <code nobreak="false">false</code>)</sitem><sitem><code nobreak="false">vendor-options</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">cache</code> (default is implementation-defined)</sitem></slist></item></olist></item><item><p>For invocation of an XSLT 3.0 or XSLT 4.0 processor (see <bibref ref="xslt-40"/>), 
                  the supplied options must include all of the following <phrase diff="chg" at="E">(if anything else is present, it is ignored)</phrase>:</p><olist><item><p>The stylesheet, provided either by supplying exactly one of the following:</p><slist><sitem>
                           <code nobreak="false">stylesheet-location</code>
                        </sitem><sitem>
                           <code nobreak="false">stylesheet-node</code>
                        </sitem><sitem>
                           <code nobreak="false">stylesheet-text</code>
                        </sitem></slist><p>Or by supplying exactly one of the following:</p><slist><sitem>
                           <code nobreak="false">package-location</code>
                        </sitem><sitem>
                           <code nobreak="false">package-node</code>
                        </sitem><sitem>
                           <code nobreak="false">package-text</code>
                        </sitem><sitem><code nobreak="false">package-name</code> plus optionally <code nobreak="false">package-version</code></sitem></slist></item><item><p>Invocation details, as exactly one of the following combinations:</p><olist><item><p>For apply-templates invocation, all of the following:</p><p>Exactly one of <code nobreak="false">source-node</code>, <code nobreak="false">source-location</code>,
                              or <code nobreak="false">initial-match-selection</code></p><p>Optionally, <code nobreak="false">initial-mode</code></p><p>Optionally, <code nobreak="false">template-params</code></p><p>Optionally, <code nobreak="false">tunnel-params</code></p></item><item><p>For call-template invocation using an explicit template name, all of the following:</p><p>
                              <code nobreak="false">initial-template</code>
                           </p><p>Optionally, <code nobreak="false">template-params</code></p><p>Optionally, <code nobreak="false">tunnel-params</code></p><p>Optionally, <code nobreak="false">source-node</code></p></item><item><p>For call-template invocation using the defaulted template name <code nobreak="false">xsl:initial-template</code>, all of the following:</p><p>Optionally, <code nobreak="false">template-params</code></p><p>Optionally, <code nobreak="false">tunnel-params</code></p><note><p>If the <code nobreak="false">source-node</code> or <code nobreak="false">source-location</code>option 
                                 is present and <code nobreak="false">initial-template</code> is absent,
                              then apply-templates invocation will be used. To use call-template invocation on the template
                              named <code nobreak="false">xsl:initial-template</code> while also supplying a context item for use when evaluating
                              global variables, either (a) supply the context item using the <code nobreak="false">global-context-item</code> option,
                              or (b) supply <code nobreak="false">source-node</code>, and set the <code nobreak="false">initial-template</code> option explicitly to the 
                              QName <code nobreak="false">xsl:initial-template</code></p></note></item><item><p>For call-function invocation, all of the following:</p><p>
                              <code nobreak="false">initial-function</code>
                           </p><p>
                              <code nobreak="false">function-params</code>
                           </p></item></olist><note><p>The invocation method can be determined as the first of the following which applies:</p><ulist><item><p>If <code nobreak="false">initial-function</code> is present, then call-function invocation.</p></item><item><p>If <code nobreak="false">initial-template</code> is present, then call-template invocation.</p></item><item><p>If <code nobreak="false">source-node</code> or <code nobreak="false">source-location</code> 
                                 or <code nobreak="false">initial-match-selection</code>
                              is present, then apply-templates invocation.</p></item><item><p>Otherwise, <code nobreak="false">call-template</code> invocation using
                              the default entry point <code nobreak="false">xsl:initial-template</code>.</p></item></ulist></note></item><item><p>Zero or more of the following additional options:</p><slist><sitem>
                           <code nobreak="false">stylesheet-base-uri</code>
                        </sitem><sitem><code nobreak="false">static-params</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">stylesheet-params</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">global-context-item</code> (defaults to absent)</sitem><sitem><code nobreak="false">base-output-uri</code> (defaults to absent)</sitem><sitem>
                           <code nobreak="false">delivery-format</code>
                        </sitem><sitem><code nobreak="false">serialization-params</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">enable-assertions</code> (default is <code nobreak="false">false</code>)</sitem><sitem><code nobreak="false">enable-messages</code> (default is implementation-defined)</sitem><sitem><code nobreak="false">enable-trace</code> (default is implementation-defined)</sitem><sitem><code nobreak="false">requested-properties</code> (default is the empty map)</sitem><sitem><code nobreak="false">trusted</code> (default is <code nobreak="false">false</code>)</sitem><sitem><code nobreak="false">vendor-options</code> (defaults to the empty map)</sitem><sitem><code nobreak="false">cache</code> (default is implementation-defined)</sitem></slist></item></olist></item></olist><p>The meanings of each option are defined in the table below.</p><example role="record"><record returnEmptyOk="no" returnSeq="no" prefix="fn" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="base-output-uri" type="xs:string" occur="opt"/><arg name="cache" type="xs:boolean" occur="opt"/><arg name="delivery-format" type="xs:string" occur="opt"/><arg name="enable-assertions" type="xs:boolean" occur="opt"/><arg name="enable-messages" type="xs:boolean" occur="opt"/><arg name="enable-trace" type="xs:boolean" occur="opt"/><arg name="function-params" type="array(item()*)" occur="opt"/><arg name="global-context-item" type="item()" occur="opt"/><arg name="initial-function" type="xs:QName" occur="opt"/><arg name="initial-match-selection" type="item()*" occur="opt"/><arg name="initial-mode" type="xs:QName" occur="opt"/><arg name="initial-template" type="xs:QName" occur="opt"/><arg name="package-name" type="xs:string" occur="opt"/><arg name="package-location" type="xs:string" occur="opt"/><arg name="package-node" type="node()" occur="opt"/><arg name="package-text" type="xs:string" occur="opt"/><arg name="package-version" type="xs:string" occur="opt"/><arg name="post-process" type="fn(xs:string, item()*) as item()*" occur="opt"/><arg name="requested-properties" type="map(xs:QName, xs:anyAtomicType)" occur="opt"/><arg name="serialization-params" type="map(xs:anyAtomicType, item()*)" occur="opt"/><arg name="source-location" type="node()" occur="opt"/><arg name="source-node" type="node()" occur="opt"/><arg name="static-params" type="map(xs:QName, item()*)" occur="opt"/><arg name="stylesheet-base-uri" type="xs:string" occur="opt"/><arg name="stylesheet-location" type="xs:string" occur="opt"/><arg name="stylesheet-node" type="node()" occur="opt"/><arg name="stylesheet-params" type="map(xs:QName, item()*)" occur="opt"/><arg name="stylesheet-text" type="xs:string" occur="opt"/><arg name="template-params" type="map(xs:QName, item()*)" occur="opt"/><arg name="tunnel-params" type="map(xs:QName, item()*)" occur="opt"/><arg name="trusted" type="xs:boolean" occur="opt"/><arg name="vendor-options" type="{ xs:QName, item()* }" occur="opt"/><arg name="xslt-version" type="xs:decimal" occur="opt"/></record></example><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Key</th><th rowspan="1" colspan="1">Applies to</th><th rowspan="1" colspan="1">Value</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">base-output-uri?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The URI of the principal result document; also used as the base URI for
            resolving relative URIs of secondary result documents. If the value is a relative 

            reference, it is resolved against the 
                  <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> 
                  of the <code nobreak="false">fn:transform</code> 
                  function call. <ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term>The effect of not
            supplying a base output URI is defined by the XSLT specification; the implementation

            <rfc2119>may</rfc2119> supply a default, for example the current working directory. 
               If the <code nobreak="false">fn:transform</code> function is called from XSLT, then
               the <rfc2119>recommended</rfc2119> default is the current output URI
               of the calling transformation.</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">cache?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">This option has no effect on the result of the transformation but may affect
            efficiency. The value <code nobreak="false">true</code> indicates an expectation that the same
            stylesheet is likely to be used for more than one transformation; the value
                <code nobreak="false">false</code> indicates an expectation that the stylesheet will be used once
            only.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">true</code></p></item></ulist></td></tr><tr><td rowspan="5" colspan="1"><p><code nobreak="false">delivery-format?</code></p></td><td rowspan="5" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thick" colspan="2" rowspan="1">The manner in which the transformation results should be delivered. Applies both to the
            principal result document and to secondary result documents created using
                <code nobreak="false">xsl:result-document</code>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">document</code></p><p>If the relevant
            <code nobreak="false">xsl:output</code> or <code nobreak="false">xsl:result-document</code> element specifies
            <code nobreak="false">build-tree="no"</code> (applies to XSLT 3.0 only), then the default
            is <code nobreak="false">raw</code>.</p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">document</code></td><td rowspan="1" colspan="1">The result is delivered as a
                        document node.</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">serialized</code></td><td rowspan="1" colspan="1">The result is delivered as
                        a string, representing the results of serialization. Note that (as with the
                            <function>fn:serialize</function> function) the final encoding stage of
                        serialization (which turns a sequence of characters into a sequence of
                        octets) is either skipped, or reversed by decoding the octet stream back
                        into a character stream.</td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">raw</code></td><td rowspan="1" colspan="1">The result of the initial
                template or function is returned as an arbitrary XDM value (after conversion
                to the declared type, but without wrapping in a document node, and without
                serialization): when this option is chosen, the returned map contains the
                raw result.</td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">file</code></td><td rowspan="1" colspan="1">The serialized result is written to persistent storage. This means that the
                  <code nobreak="false">fn:transform</code> function has side-effects and becomes nondeterministic,
                  so the option should be used with care, and the precise behavior may
                  be <termref def="implementation-defined"/>. When this option is used,
                  the URIs used for the <code nobreak="false">base-output-uri</code> and the URIs of any
                  secondary result documents must be writable locations.</td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">enable-assertions?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">Indicates whether any <code nobreak="false">xsl:assert</code> instructions in the stylesheet
            are to be evaluated.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">enable-messages?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">Indicates whether any <code nobreak="false">xsl:message</code> instructions in the stylesheet
            are to be evaluated. The destination and formatting of any such messages is
            <termref def="implementation-defined"/>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><termref def="implementation-defined">Implementation-defined</termref>.</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">enable-trace?</code></p></td><td rowspan="1" colspan="1">2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">Indicates whether any <function>fn:trace</function> functions in the stylesheet are to
            generate diagnostic messages. The destination and formatting of any such messages is
            implementation-defined.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><termref def="implementation-defined">Implementation-defined</termref>.</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">function-params?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">An array of values to be used as the arguments to the initial function call.
            The value is converted to the required type of the declared parameter using the function
            conversion rules.<ulist><item><p><term>Type: </term><code nobreak="false">array(item()*)</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty array</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">global-context-item?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The value of the global context item, as defined in XSLT 3.0<ulist><item><p><term>Type: </term><code nobreak="false">item()</code></p></item><item><p><term>Default: </term>The value of <code nobreak="false">source-node</code>, if supplied</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">initial-function?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The name of the initial function to be called for call-function invocation. The
            arity of the function is inferred from the length of
            <code nobreak="false">function-params</code>.<ulist><item><p><term>Type: </term><code nobreak="false">xs:QName</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">initial-match-selection?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The value of the initial match selection, as defined in XSLT 3.0<ulist><item><p><term>Type: </term><code nobreak="false">item()*</code></p></item><item><p><term>Default: </term>The value of <code nobreak="false">source-node</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">initial-mode?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The name of the initial processing mode.<ulist><item><p><term>Type: </term><code nobreak="false">xs:QName</code></p></item><item><p><term>Default: </term>none</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">initial-template?</code></p></td><td rowspan="1" colspan="1">2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The name of a named template in the stylesheet to act as the initial entry
            point.<ulist><item><p><term>Type: </term><code nobreak="false">xs:QName</code></p></item><item><p><term>Default: </term><code nobreak="false">xsl:initial-template</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">package-name?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The name of the top-level stylesheet package to be invoked (an absolute
            URI)<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">package-location?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The location of the top-level stylesheet package, as a relative or absolute
            URI<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">package-node?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">A document or element node containing the top-level stylesheet
            package<ulist><item><p><term>Type: </term><code nobreak="false">node()</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">package-text?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The top-level stylesheet package in the form of unparsed lexical
            XML.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">package-version?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The version of the top-level stylesheet package to be invoked.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term><code nobreak="false">"*" (any version)</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">post-process?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">A function that is used to post-process each result document of
                  the transformation (both the principal result and secondary results), in whatever
                  form it would otherwise be delivered (document, serialized, or raw). The first 

                  argument of the function is the key used to identify the result in the map return
                  by the <function>fn:transform</function> function (for example, this will be the supplied
                  base output URI in the case of the principal result, or the string “output” if no
                  base output URI was supplied). The second argument is the 
                  actual value. The value that is returned in the result of the <function>fn:transform</function> 
                  function is the result of applying this post-processing.
                  
                  <note><p>If the implementation provides a way of writing or invoking functions 
                        with side-effects, this post-processing function might be used to save 
                        a copy of the result document to persistent storage. For example, if the 
                        implementation provides access to the EXPath File library <bibref ref="expath"/>, 
                        then a serialized document might be written to filestore by calling the 
                        <code nobreak="false">file:write</code> function. Similar mechanisms might be used to issue 
                        an HTTP POST request that posts the result to an HTTP server, or to send 
                        the document to an email recipient. The semantics of calling functions 
                        with side-effects are entirely <termref def="implementation-defined">implementation-defined</termref>.</p><p>If the primary purpose of the post-processing function is achieved by 
                        means of such side-effects, and if the actual results are not needed by 
                        the caller of the <function>fn:transform</function> function, then it does not matter what 
                        the post-processing function actually returns (it could be the empty 
                        sequence, for example).</p><p>Calls to <function>fn:transform</function> can potentially have side-effects 
                        even in the absence of the post-processing option, because the XSLT 
                        specification allows a stylesheet to invoke extension functions 
                        that have side-effects. The semantics in this case are <termref def="implementation-defined">implementation-defined</termref>.</p></note><ulist><item><p><term>Type: </term><code nobreak="false">fn(xs:string, item()*) as item()*</code></p></item><item><p><term>Default: </term><code nobreak="false">fn($a, $b) { $b }</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">requested-properties?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The keys in the map are QNames that could legitimately be supplied in a call to
            the XSLT <code nobreak="false">system-property</code> function; the values in the map are the requested
            settings of the corresponding property. The boolean values <code nobreak="false">true</code> and
                <code nobreak="false">false</code> are equivalent to the string values <code nobreak="false">yes</code> and
                <code nobreak="false">no</code>. As a special case, setting a value for <code nobreak="false">xsl:version</code> has
            no effect, because of the potential for conflict with other options. For example: <ulist><item><p>Setting <code nobreak="false">xsl:product-name</code> to a particular value requests a
                        particular XSLT software product.</p></item><item><p>Setting <code nobreak="false">xsl:product-version</code> requests a specific version of
                        that product.</p></item><item><p>Setting <code nobreak="false">xsl:is-schema-aware</code> to <code nobreak="false">true</code> requests a
                        schema-aware processor.</p></item><item><p>Setting <code nobreak="false">xsl:xsd-version</code> to <code nobreak="false">"1.1"</code> requests a
                        processor that supports XML Schema version 1.1.</p></item></ulist> Setting a boolean property such as <code nobreak="false">xsl:supports-dynamic-evaluation</code>
            to <code nobreak="false">false</code> is interpreted as an explicit request for a processor in which
            the value of the property is <code nobreak="false">false</code>. The effect if the requests cannot be precisely met
            is implementation-defined. In some cases it may be appropriate to ignore the request or
            to provide an alternative (for example, a later version of the product than the one
            requested); in other cases it may be more appropriate to raise an error <errorref class="XT" code="0001" type="dynamic"/> indicating that no suitable XSLT processor
            is available. <ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, xs:anyAtomicType)</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty map</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">serialization-params?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">Serialization parameters for the principal result document. The supplied map
            follows the same rules that apply to a map supplied as the second argument of
                <function>fn:serialize</function>. <ulist><item><p>When a parameter is supplied, the corresponding value overrides or augments
                        the value specified in the unnamed <code nobreak="false">xsl:output</code> declaration (or
                        its default), following the same rules as when one <code nobreak="false">xsl:output</code>
                        declaration overrides another with lower import precedence.</p></item><item><p>When a parameter is supplied and the corresponding value is the empty
                        sequence (for example, <code nobreak="false">{ "standalone": () }</code>), any value
                        specified in the unnamed <code nobreak="false">xsl:output</code> declaration is overridden
                        by the default value. </p></item><item><p>When a parameter is not supplied in <code nobreak="false">serialization-params</code> (that
                        is, when the key is absent) the value that applies is the value appearing in
                        the unnamed <code nobreak="false">xsl:output</code> declaration, or its default. </p></item></ulist><ulist><item><p><term>Type: </term><code nobreak="false">map(xs:anyAtomicType, item()*)</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty map</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">source-location?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">When <code nobreak="false">source-location</code> is supplied then 
                  it is expected to be an absolute or relative URI identifying an
                  unparsed XML document. If relative, it
                  is resolved against the static base URI of the <code nobreak="false">fn:transform</code> function call.
                  The document at this location is parsed,
                  and the document node acts as the
                  <code nobreak="false">initial-match-selection</code>, that is, stylesheet execution starts by
                  applying templates to this node. If the initial mode is streamable
                  and a streaming XSLT 3.0 or XSLT 4.0 processor is used,
                  then the supplied document is processed in streaming mode.<ulist><item><p><term>Type: </term><code nobreak="false">node()</code></p></item><item><p><term>Default: </term><code nobreak="false">n/a</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">source-node?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">When <code nobreak="false">source-node</code> is supplied then the
                <code nobreak="false">global-context-item</code> (the context item for evaluating global variables)
            is the root of the tree containing the supplied node. In addition, for apply-templates
            invocation, the <code nobreak="false">source-node</code> acts as the
                <code nobreak="false">initial-match-selection</code>, that is, stylesheet execution starts by
            applying templates to this node.<ulist><item><p><term>Type: </term><code nobreak="false">node()</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">static-params?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The values of static parameters defined in the stylesheet; the keys are the
            names of the parameters, and the associated values are their values. The value is
            converted to the required type of the declared parameter using the coercion
            rules.<ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, item()*)</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty map</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">stylesheet-base-uri?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">A string intended to be used as the static base URI of the principal stylesheet
            module. This value <rfc2119>must</rfc2119> be used if no other static base URI is
            available. If the supplied stylesheet already has a base URI (which will generally be
            the case if the stylesheet is supplied using <code nobreak="false">stylesheet-node</code> or
                <code nobreak="false">stylesheet-location</code>) then it is <termref def="implementation-defined">implementation-defined</termref> whether this
            parameter has any effect. If the value is a relative reference, it is resolved against

            the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> 
                  of the <code nobreak="false">fn:transform</code> function call.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">stylesheet-location?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">URI that can be used to locate the principal stylesheet module. If relative, it

            is resolved against the <xtermref spec="XP40" ref="dt-executable-base-uri">executable base URI</xtermref> 
                  of the <code nobreak="false">fn:transform</code> function call.

            The value also acts as the default for stylesheet-base-uri.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">stylesheet-node?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">Root of the tree containing the principal stylesheet module, as a document or
            element node. The base URI of the node acts as the default for
            stylesheet-base-uri.<ulist><item><p><term>Type: </term><code nobreak="false">node()</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">stylesheet-params?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">A map holding values to be supplied for stylesheet parameters. The keys are the
            parameter names; the values are the corresponding parameter values. The values are
            converted if necessary to the required type using the coercion rules. The
            default is the empty map.<ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, item()*)</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty map</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">stylesheet-text?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The principal stylesheet module in the form of unparsed lexical
            XML.<ulist><item><p><term>Type: </term><code nobreak="false">xs:string</code></p></item><item><p><term>Default: </term>n/a</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">template-params?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The values of non-tunnel parameters to be supplied to the initial template,
            used with both apply-templates and call-template invocation. Each value is converted to
            the required type of the declared parameter using the coercion
            rules.<ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, item()*)</code></p></item><item><p><term>Default: </term>none</p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">tunnel-params?</code></p></td><td rowspan="1" colspan="1">3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The values of tunnel parameters to be supplied to the initial template, used
            with both apply-templates and call-template invocation. Each value is converted to the
            required type of the declared parameter using the coercion
            rules.<ulist><item><p><term>Type: </term><code nobreak="false">map(xs:QName, item()*)</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty map</code></p></item></ulist></td></tr><tr><td rowspan="3" colspan="1"><p><code nobreak="false">trusted?</code></p></td><td rowspan="3" colspan="1"/><td class="fos-thick" colspan="2" rowspan="1">Indicates whether the target stylesheet is 
                  trusted to access external resources. This applies both to resources
               statically referenced by the stylesheet (for example using
               <code nobreak="false">xsl:include</code>, <code nobreak="false">xsl:import</code>, <code nobreak="false">xsl:use-package</code>,
                  or <code nobreak="false">xsl:import-schema</code>), and to resources accessed dynamically by
               executing the retrieved stylesheet, for example by use of the
               <function>fn:doc</function> or <function>unparsed-text</function> function.<ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item><item><p><term>Default: </term><code nobreak="false">false()</code></p></item></ulist></td></tr><tr><td class="fos-thin" rowspan="1" colspan="1"><code nobreak="false">true</code></td><td rowspan="1" colspan="1">The loaded stylesheet has the same level of trust
                     as the caller, and may therefore access all external resources
                     available to the caller.
                  </td></tr><tr><td class="fos-thick" rowspan="1" colspan="1"><code nobreak="false">false</code></td><td rowspan="1" colspan="1">The loaded stylesheet is <xtermref spec="XP40" ref="dt-untrusted">untrusted</xtermref>, and
                     is therefore unable to access external resources unless these have been made
                     explicitly available by a trusted caller.
                  </td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">vendor-options?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">Values for vendor-defined configuration options for the XSLT processor used to
            process the request. The key is the name of an option, expressed as a QName: the
            namespace URI of the QName <rfc2119>should</rfc2119> be a URI controlled by the vendor
            of the XSLT processor. The meaning of the associated value is <termref def="implementation-defined">implementation-defined</termref>. Implementations
                <rfc2119>should</rfc2119> ignore options whose names are in an unrecognized
            namespace. Default is the empty map.<ulist><item><p><term>Type: </term><code nobreak="false">{ xs:QName, item()* }</code></p></item><item><p><term>Default: </term><code nobreak="false">Empty map</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">xslt-version?</code></p></td><td rowspan="1" colspan="1">1.0, 2.0, 3.0, 4.0</td><td class="fos-thin" colspan="2" rowspan="1">The minimum level of the XSLT language that the processor must support.<ulist><item><p><term>Type: </term><code nobreak="false">xs:decimal</code></p></item><item><p><term>Default: </term>The <code nobreak="false">[xsl:]version</code> attribute at the outermost level of the
            stylesheet.</p></item></ulist></td></tr></tbody></table><p>The result of the transformation is returned as a map. There is one entry in the map for the principal result document, and one
            for each secondary result document. The key is a URI in the form of an <code nobreak="false">xs:string</code> value. The key for the principal
            result document is the base output URI if specified, or the string <code nobreak="false">"output"</code> otherwise. The key for secondary
            result documents is the URI of the document, as an absolute URI. The associated value in each entry depends on the requested
            delivery format. If the delivery format is <code nobreak="false">document</code>, the value is a document node. If the delivery format is
            <code nobreak="false">serialized</code>, the value is a string containing the serialized result. </p><p>Where nodes are passed to or from the transformation, for example as the value of a stylesheet parameter or the result of a function, 
            they <rfc2119>should</rfc2119> if possible retain their node identity, their base URI, their type annotations, and their relationships to all other nodes 
            in the containing tree (including ancestors and siblings). If this is not possible, for example because the only way of passing nodes 
            to the chosen XSLT implementation is by serializing and re-parsing, then a node <rfc2119>may</rfc2119> be passed in the form of a deep 
            copy, which may lose information about the identity of the node, about its ancestors and siblings, about its base URI, about its type annotation, and about its 
            relationships to other nodes passed across the interface.</p><p>It is <termref def="implementation-defined">implementation-defined</termref> whether the XSLT transformation is executed
            within the same <termref def="execution-scope">execution scope</termref> as the calling code.</p><p>The function is <termref def="dt-nondeterministic">nondeterministic</termref> in that it is 
            <termref def="implementation-dependent">implementation-dependent</termref> whether running the function twice against the same
         inputs produces identical results. The results of two invocations may differ in the identity of any returned nodes; they may also
         differ in other respects, for example because the value of <function>fn:current-dateTime</function> is different for the two invocations,
         or because the contents of external documents accessed using <function>fn:doc</function> or <code nobreak="false">xsl:source-document</code> change between
         one invocation and the next.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A dynamic error is raised <errorref class="XT" code="0001" type="dynamic"/> if the transformation cannot be invoked 
            because no suitable XSLT processor is available. This includes (but is not limited to) the following cases:</p><olist><item><p>No XSLT processor is available;</p></item><item><p>No XSLT processor supporting the requested version of XSLT is available;</p></item><item><p>The XSLT processor API does not support some requested feature (for example, the ability to supply tunnel parameters externally);</p></item></olist><p>A dynamic error is raised <errorref class="XT" code="0002" type="dynamic"/> if an error is detected in the supplied
            parameters (for example if two mutually exclusive parameters are supplied).</p><p>If a static or dynamic error is reported by the XSLT processor, this function fails with a dynamic error, retaining the XSLT error code.</p><p>A dynamic error is raised <errorref class="XT" code="0003" type="dynamic"/> if the XSLT transformation invoked by a call on
            <function>fn:transform</function> fails with a static or dynamic error, and no more specific error code is available. </p><note><p>XSLT 1.0 does not define any error codes, so this is the likely outcome with an XSLT 1.0 processor. XSLT 2.0 and 3.0 do
         define error codes, but some APIs do not expose them. If multiple errors are signaled by the transformation (which is most likely
         to happen with static errors) then the error code should where possible be that of one of these errors, chosen arbitrarily; the processor
         may make details of additional errors available to the application in an <termref def="implementation-defined">implementation-defined</termref>
         way.</p></note><p>A dynamic error is raised <errorref class="XT" code="0004" type="dynamic"/> if the use of this function (or of selected options)
            has been externally disabled, for example for security reasons.</p><p>A dynamic error is raised <errorref class="XT" code="0006" type="dynamic"/> if the transformation produces output containing
            characters available only in XML 1.1, and the calling processor cannot handle such characters.</p><p>Recursive use of the <function>fn:transform</function> function may lead to catastrophic failures such as
         non-termination or stack overflow. No error code is assigned to such conditions, since they cannot necessarily
         be detected by the processor.</p></def></gitem><gitem><label>Notes</label><def><note><p>As with all other functions in this specification, conformance requirements depend on the host language.
            For example, a host language might specify that provision of this function is optional, or that it is excluded entirely,
            or that implementations are required to support a particular set of values for the <code nobreak="false">xslt-version</code>
            parameter.</p><p>Even where support for this function is mandatory, it is <rfc2119>recommended</rfc2119> for security reasons that implementations
            should provide a user option to disable its use, or to disable aspects of its functionality such as
            the ability to write to persistent resources.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr><td colspan="2" rowspan="1"><p>The following example loads a stylesheet from the location <code nobreak="false">render.xsl</code>,
               applies it to a document loaded from <code nobreak="false">test.xml</code>, and uses an XPath expression
               to examine the result:</p></td></tr><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">
let $result := transform({
  "stylesheet-location": "render.xsl",
  "source-node": doc('test.xml')
})
return $result?output//body  
               </eg></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-op"><head>fn:op</head><changes><change issue="83" PR="173" date="2022-10-11">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a function whose effect is to apply a supplied binary operator to two arguments.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="op" return-type="fn(item()*, item()*) as item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="operator" type="xs:string"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The supplied operator must be one of:</p><p><code nobreak="false">","</code>, <code nobreak="false">"and"</code>, <code nobreak="false">"or"</code>, <code nobreak="false">"+"</code>,
            <code nobreak="false">"-"</code>, <code nobreak="false">"*"</code>, <code nobreak="false">"div"</code>, <code nobreak="false">"idiv"</code>,
            <code nobreak="false">"mod"</code>, <code nobreak="false">"="</code>, <code nobreak="false">"&lt;"</code>, <code nobreak="false">"&lt;="</code>,
            <code nobreak="false">"&gt;"</code>, <code nobreak="false">"&gt;="</code>, <code nobreak="false">"!="</code>, <code nobreak="false">"eq"</code>,
            <code nobreak="false">"lt"</code>, <code nobreak="false">"le"</code>, <code nobreak="false">"gt"</code>, <code nobreak="false">"ge"</code>,
            <code nobreak="false">"ne"</code>, <code nobreak="false">"&lt;&lt;"</code>, <code nobreak="false">"&gt;&gt;"</code>,
            <code nobreak="false">"precedes"</code>, <code nobreak="false">"follows"</code>, <code nobreak="false">"precedes-or-is"</code>, <code nobreak="false">"follows-or-is"</code>,
            <code nobreak="false">"is"</code>, <code nobreak="false">"is-not"</code>, <code nobreak="false">"||"</code>, <code nobreak="false">"|"</code>, <code nobreak="false">"union"</code>,
            <code nobreak="false">"except"</code>, <code nobreak="false">"intersect"</code>, <code nobreak="false">"to"</code>,
            <code nobreak="false">"otherwise"</code>.</p><p>The result of calling <code nobreak="false">fn:op("⊙")</code>, where <code nobreak="false">⊙</code> is one of the above operators, is
         the function represented by the XPath expression:</p><p><code nobreak="false">fn($x, $y) { $x ⊙ $y }</code></p><p>For example, <code nobreak="false">op("+")</code> returns <code nobreak="false">fn($x, $y) { $x + $y }</code>.</p></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <xerrorref spec="XP" class="TY" code="0004" type="type"/> if the
            supplied argument is not one of the supported operators.
         </p></def></gitem><gitem><label>Notes</label><def><note><p>The function is useful in contexts where an arity-2 callback function needs to be supplied, and
            a standard operator meets the requirement.</p><p>For example, the XSLT <code nobreak="false">xsl:map</code> instruction
            has an <code nobreak="false">on-duplicates</code> attribute that expects such a function. Specifying
         <code nobreak="false">on-duplicates="op(',')"</code> is equivalent to specifying 
         <code nobreak="false">on-duplicates="fn($x, $y) { $x, $y }</code></p><p>The function is also useful in cases where the choice of operator to apply is
         made dynamically.</p><p>Some operators (such as <code nobreak="false">and</code>, <code nobreak="false">or</code>, and <code nobreak="false">otherwise</code>)
         have custom error handling semantics, with the effect that evaluating one of the operands cannot
         cause an error unless the other operand has a particular value 
         (see <xspecref spec="XP40" ref="id-guarded-expressions"/>). Although implementations are free
         to make optimizations, it should be assumed that a function call such as <code nobreak="false">op('and')(X, Y)</code>
         will have the normal semantics of a dynamic function call, where the arguments are evaluated in any order,
         and a failure evaluating any argument may cause the function call as a whole to fail.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">for-each-pair(21 to 25, 1 to 5, op("+"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">22, 24, 26, 28, 30</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">for-each-pair(21 to 25, 1 to 5, op("-"))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">20, 20, 20, 20, 20</code></p></td></tr></tbody></table></def></gitem></glist></div2></div1><div1 id="functions-on-types"><head>Processing types</head><changes><change issue="148" PR="1523" date="2024-11-05">
                 New functions are provided to obtain information about built-in types and types defined in an
                 imported schema.
              </change></changes><p>The functions in this section deliver information about schema types (including simple types and complex
         types). These may represent built-in types (such as <code nobreak="false">xs:dateTime</code>), 
            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.</p><p>For more information on schema types, see <specref ref="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 <xspecref spec="XS11-1" ref="Simple_Type_Definition_details"/>
         and <xspecref spec="XS11-1" ref="Complex_Type_Definition_details"/> respectively. Not all properties are exposed.</p><p>The structured representation of a schema type is described in
           <specref ref="schema-type-record"/>.</p><note><p>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, <code nobreak="false">base-type</code> and <code nobreak="false">primitive-type</code>)
            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 <code nobreak="false">xs:decimal</code> is itself
            <code nobreak="false">xs:decimal</code>, 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.</p></note><div2 id="functions-returning-type-information"><head>Functions returning type information</head><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:schema-type</code></td><td rowspan="1" colspan="1">Returns a record containing information about a named schema type in the static context.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:type-of</code></td><td rowspan="1" colspan="1">Returns information about the type of a value, as a string.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:atomic-type-annotation</code></td><td rowspan="1" colspan="1">Returns a record containing information about the type annotation of an atomic value.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:node-type-annotation</code></td><td rowspan="1" colspan="1">Returns a record containing information about the type annotation of an element or attribute node.</td></tr></tbody></table><div3 id="schema-type-record"><head>Record fn:schema-type-record</head><p>This record type represents the properties of a simple or complex type in a schema.</p><table class="fos-options"><thead><tr><th rowspan="1" colspan="1">Name</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td rowspan="1" colspan="1"><p><code nobreak="false">name</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>The name of the type. Empty in the case of an anonymous type. Corresponds to
            <xtermref spec="XS11-1" ref="ctd-name">{name}</xtermref> and 
               <xtermref spec="XS11-1" ref="ctd-target_namespace">{target namespace}</xtermref>
               in the XSD component model for simple and complex type
            components.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:QName?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">is-simple</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>True for a simple type, false for a complex type.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">xs:boolean</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">base-type</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>Function item returning the base type (the type from which this type is derived by restriction 
               or extension). The function is always present, and returns the empty sequence
               in the case of the type <code nobreak="false">xs:anyType</code>. Corresponds to the 
               <xtermref spec="XS11-1" ref="ctd-base_type_definition">{base type definition}</xtermref> property
            in the XSD component model.</p>
            
         <ulist><item><p><term>Type: </term><code nobreak="false">fn() as schema-type-record?</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">primitive-type?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>For an atomic type, a function item returning the primitive type from which this 
               type is ultimately derived. Corresponds to the
               <xtermref spec="XS11-1" ref="std-primitive_type_definition">{primitive type definition}</xtermref> in the XSD 
               component model for simple types. Absent if the type is non atomic, or if it is 
               the simple type <code nobreak="false">xs:anyAtomicType</code>. If this is a primitive type, the
               function item is idempotent.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">fn() as schema-type-record</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">variety?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>For a simple type, one of <code nobreak="false">"atomic"</code>, <code nobreak="false">"list"</code>, or <code nobreak="false">"union"</code>, corresponding to the
               <xtermref spec="XS11-1" ref="std-variety">{variety}</xtermref> of the simple type in the XSD component model. For a complex type, one of
            <code nobreak="false">"empty"</code>, <code nobreak="false">"simple"</code>, <code nobreak="false">"element-only"</code>, or <code nobreak="false">"mixed"</code>, 
               corresponding to the <xtermref spec="XS11-1" ref="ctd-content_type">{content type}</xtermref>.<xtermref spec="XS11-1" ref="ct-variety">{variety}</xtermref> 
               of the complex type in the XSD component model. The value is absent in cases where the 
            <xtermref spec="XS11-1" ref="std-variety">{variety}</xtermref> in the XSD component model is absent, for example
            for the type <code nobreak="false">xs:anySimpleType</code>.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">enum("atomic", "list", "union", "empty", "simple", "element-only", "mixed")</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">members?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>For a simple type with variety <code nobreak="false">"union"</code>, a function that returns a sequence of
               records representing the member types of the union, in order, corresponding to the
               <xtermref spec="XS11-1" ref="std-member_type_definitions">{member type definitions}</xtermref>
               property in the XSD component model. 
               For a simple type with variety <code nobreak="false">"list"</code>,
            a function that returns a record representing the item type of the list type, corresponding to
            the <xtermref spec="XS11-1" ref="std-item_type_definition">{item type definition}</xtermref> property in the XSD component model. In all other cases, absent.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">fn() as schema-type-record*</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">simple-content-type?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>For a complex type with variety <code nobreak="false">"simple"</code> (that is, a complex type with simple content), 
               a function that returns a record representing the relevant simple type, corresponding to 
               the <xtermref spec="XS11-1" ref="ctd-content_type">{content type}</xtermref>.<xtermref spec="XS11-1" ref="ct-simple_type_definition">{simple type definition}</xtermref>              
               property in the XSD complex type component. 
               In all other cases, absent.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">fn() as schema-type-record</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">matches?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>For a <xtermref spec="XP40" ref="dt-generalized-atomic-type"/>, 
               a function item that can be called to establish whether the supplied atomic item
               is an instance of this type. In all other cases, absent.</p>
         <ulist><item><p><term>Type: </term><code nobreak="false">fn(xs:anyAtomicType) as xs:boolean</code></p></item></ulist></td></tr><tr><td rowspan="1" colspan="1"><p><code nobreak="false">constructor?</code></p></td><td class="fos-thin" rowspan="1" colspan="1">
            <p>For a simple type, a function item that can be used to construct instances of this type. In the case of a named
             type that is present in the dynamic context, the result is the same function as returned by 
               <function>fn:function-lookup</function> applied to the type name (with arity one). 
               For details see <specref ref="constructor-functions-for-xsd-types"/>
               and <specref ref="constructor-functions-for-user-defined-types"/>. 
               Constructor function items are also available for
               anonymous types, and for types that might not be present in the dynamic context. 
               The field is absent for complex types and for the abstract types <code nobreak="false">xs:anyAtomicType</code>,
               <code nobreak="false">xs:anySimpleType</code>, and
               <code nobreak="false">xs:NOTATION</code>. It is also absent for all <xtermref spec="XP40" ref="dt-namespace-sensitive"/> types.
            </p>
         <ulist><item><p><term>Type: </term><code nobreak="false">fn(xs:anyAtomicType?) as xs:anyAtomicType*</code></p></item></ulist></td></tr></tbody></table></div3><div3 id="func-schema-type"><head>fn:schema-type</head><changes><change issue="148" PR="1523" date="2024-10-22">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a record containing information about a named schema type in the static context.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="schema-type" return-type-ref="schema-type-record" return-type-ref-occurs="?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="name" type="xs:QName"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>If the static context (specifically, the <xtermref spec="XP40" ref="dt-is-types">in-scope schema types</xtermref>) 
            includes a schema type whose name matches <code nobreak="false">$name</code>, 
            the function returns a <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#schema-type-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">schema-type-record</loc>
         containing information about that schema type. If not, it returns the empty sequence.</p></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">schema-type( #xs:integer ) ? name</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#xs:integer</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">schema-type( #xs:long ) ? primitive-type() ? name</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#xs:decimal</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">schema-type( #xs:positiveInteger ) ? base-type() ? name</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#xs:nonNegativeInteger</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">schema-type( #xs:integer ) ? matches(23)</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">true()</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">schema-type( #xs:numeric ) ? variety</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"union"</code></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">schema-type( #xs:numeric ) ? members() ? name</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">#xs:double, #xs:float, #xs:decimal</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-type-of"><head>fn:type-of</head><changes><change issue="1550" PR="1570" date="2024-11-12">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns information about the type of a value, as a string.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="type-of" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="item()*"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns a string, whose lexical form will always match
            the grammar of <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XP40" ref="SequenceType" xlink:type="simple">SequenceType</xnt>, representing a sequence type that matches
         <code nobreak="false">$value</code>.</p><p>If <code nobreak="false">$value</code> is the empty sequence, the function returns the string <code nobreak="false">"empty-sequence()"</code>.</p><p>Otherwise, the returned string is the concatenation of:</p><olist><item><p>A string representing the distinct item types that are present in <code nobreak="false">$value</code>,
               formed as follows:</p><olist><item><p>For each item in <code nobreak="false">$value</code>, construct a string representing its item type
                  as described below.</p></item><item><p>Eliminate duplicate strings from this list by applying the <function>fn:distinct-values</function>
                  function, forming a sequence of strings <var>$ss</var>.</p></item><item><p>If <var>$ss</var> contains only one string, use that string.</p></item><item><p>Otherwise, return the result of the expression <code nobreak="false">`({ fn:string-join(<var>$ss</var>, "|") })`</code>.</p></item></olist></item><item><p>An occurrence indicator: absent if <code nobreak="false">$value</code> contains exactly one item, or
            <code nobreak="false">"+"</code> if it contains more than one item.</p></item></olist><p>The string representing the type of an individual item <var>J</var> is constructed as follows:</p><olist><item><p>If <var>J</var> is an <xtermref spec="DM40" ref="dt-XNode"/>, the result is one of the following
            strings, determined by the node kind of the node (see <xspecref spec="DM40" ref="dm-node-kind"/>):</p><p><slist><sitem><code nobreak="false">"document-node()"</code></sitem><sitem><code nobreak="false">"element()"</code></sitem><sitem><code nobreak="false">"attribute()"</code></sitem><sitem><code nobreak="false">"text()"</code></sitem><sitem><code nobreak="false">"processing-instruction()"</code></sitem><sitem><code nobreak="false">"comment()"</code></sitem><sitem><code nobreak="false">"namespace-node()"</code></sitem></slist></p></item><item><p>If <var>J</var> is a <xtermref spec="DM40" ref="dt-JNode"/>, the result is the string <code nobreak="false">"jnode()"</code>.</p></item><item><p>If <var>J</var> is an atomic item, the result is a string chosen as follows:</p><olist><item><p>Let <var>T</var> be the type denoted by the type annotation of <var>J</var>.</p></item><item><p>If <var>T</var> is an anonymous type, set <var>T</var> to the base type of <var>T</var>, and
                  repeat until a type is reached that is not anonymous.</p></item><item><p>If the name of <var>T</var> is in the namespace <code nobreak="false">http://www.w3.org/2001/XMLSchema</code>,
                  return the string <code nobreak="false">"xs:<var>local</var>"</code> where <var>local</var> is the local part of the
                  name of <var>T</var>.</p></item><item><p>Otherwise, return the name of <var>T</var> in the form of a 
                     <xnt xmlns:xlink="http://www.w3.org/1999/xlink" spec="XP40" ref="URIQualifiedName" xlink:type="simple">URIQualifiedName</xnt> (that is, <code nobreak="false">"Q{<var>uri</var>}<var>local</var>"</code>,
                     or <code nobreak="false">"Q{}<var>local</var>"</code> if the name is in no namespace).</p></item></olist></item><item><p>If <var>J</var> is a function item:</p><olist><item><p>If <var>J</var> is an array, return <code nobreak="false">"array(*)"</code>.</p></item><item><p>If <var>J</var> is a map, return <code nobreak="false">"map(*)"</code>.</p></item><item><p>Otherwise, return <code nobreak="false">"fn(*)"</code>.</p></item></olist></item></olist></def></gitem><gitem><label>Error Conditions</label><def><p>If the <code nobreak="false">$value</code> argument is omitted and the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>, the function raises
                  type error <xerrorref spec="XP" class="DY" code="0002" type="type"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>In general, an item matches more than one type, and there are cases where there is no single matching type that
         is more specific than all the others. This is especially true with functions, maps, and arrays. This function therefore
         selects one of the types that matches the item, which is not necessarily the most specific type.</p><p>This function should not be used as a substitute for an <code nobreak="false">instance of</code> test. The precise type annotation
         of the result of an expression is not always predictable, because processors are free to deliver a more specific type
         than is mandated by the specification. For example, if <code nobreak="false">$n</code> is of type <code nobreak="false">xs:positiveInteger</code>,
         then the result of <code nobreak="false">abs($n)</code> is guaranteed to be an instance of <code nobreak="false">xs:integer</code>, but an 
         implementation might reasonably return the supplied value unchanged: that is, a value whose actual type 
         annotation is <code nobreak="false">xs:positiveInteger</code>. Similarly the type annotation of the value returned by
         <code nobreak="false">position()</code> might be <code nobreak="false">xs:long</code> rather than <code nobreak="false">xs:integer</code>.</p><p>Implementations <rfc2119>should</rfc2119>, however, refrain from exposing types that are purely internal.
         For example, an implementation might have an optimized internal representation for strings consisting entirely
         of ASCII characters, or for single-character strings; if this is the case then the type annotation returned by this function
         should be a user-visible supertype such as <code nobreak="false">xs:string</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Variables</th></tr></thead><tbody><tr><td colspan="2" rowspan="1"><eg xml:space="preserve">let $e := &lt;doc&gt;
  &lt;p id="alpha" xml:id="beta"&gt;One&lt;/p&gt;
  &lt;p id="gamma" xmlns="http://example.com/ns"&gt;Two&lt;/p&gt;
  &lt;ex:p id="delta" xmlns:ex="http://example.com/ns"&gt;Three&lt;/ex:p&gt;
  &lt;?pi 3.14159?&gt;
&lt;/doc&gt;
         </eg></td></tr></tbody></table><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of($e//*[@id = 'alpha'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"element()"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of($e//*)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"element()+"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of($e//@id[. = 'gamma'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"attribute()"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of($e//node()[. = '3.14159'])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"processing-instruction()"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of($e//no-such-node)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"empty-sequence()"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of($e/child::node())</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"(element()|processing-instruction())+"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of(1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"xs:integer"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of(1 to 5)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"xs:integer+"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of((1, 1.2, 2))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"(xs:integer|xs:decimal)+"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of([ 1, 2, 3 ])</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"array(*)"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of({ 'a': 1 })</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"map(*)"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of(type-of#1)</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"fn(*)"</code></p></td></tr><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">type-of(jtree([]))</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">"jnode(array(*))"</code></p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-atomic-type-annotation"><head>fn:atomic-type-annotation</head><changes><change issue="148" PR="1523" date="2024-10-22">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a record containing information about the type annotation of an atomic value.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="atomic-type-annotation" return-type-ref="schema-type-record" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="value" type="xs:anyAtomicType"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Given an atomic value, the function returns a <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#schema-type-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">schema-type-record</loc>
         containing information about the atomic type represented by its <xtermref spec="DM40" ref="dt-type-annotation"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The result will always have <code nobreak="false">?is-simple = true()</code> and <code nobreak="false">?variety = "atomic"</code>. In a non-schema-aware
         environment the type will always be a built-in atomic type in the <code nobreak="false">xs</code> namespace: see
         <specref ref="atomic-type-hierarchy"/>. Where a schema is in use, however, the result may be an atomic type defined
         in the schema, which may be an anonymous type.</p><p>Note that under the function coercion rules, it is possible to supply a node as the argument, which
         will then be atomized. In simple cases the type annotation on the atomized value will be the same as
         the type annotation on the node. But this is not always true: for example the type annotation on
         the node might be a complex type with simple content, while the type annotation on its atomized
         value is the corresponding simple content type. To get the type annotation on the node, use the function
         <function>fn:node-type-annotation</function>.</p><p>This function should not be used as a substitute for an <code nobreak="false">instance of</code> test. The precise type annotation
         of the result of an expression is not always predictable, because processors are free to deliver a more specific type
         than is mandated by the specification. For example, if <code nobreak="false">$n</code> is of type <code nobreak="false">xs:positiveInteger</code>,
         then the result of <code nobreak="false">abs($n)</code> is guaranteed to be an instance of <code nobreak="false">xs:integer</code>, but an 
         implementation might reasonably return the supplied value unchanged: that is, a value whose actual type 
         annotation is <code nobreak="false">xs:positiveInteger</code>. Similarly the type annotation of the value returned by
         <code nobreak="false">position()</code> might be <code nobreak="false">xs:long</code> rather than <code nobreak="false">xs:integer</code>.</p><p>Implementations <rfc2119>should</rfc2119>, however, refrain from exposing types that are purely internal.
         For example, an implementation might have an optimized internal representation for strings consisting entirely
         of ASCII characters, or for single-character strings; if this is the case then the type annotation returned by this function
         should be a user-visible supertype such as <code nobreak="false">xs:string</code>.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">atomic-type-annotation(23) ? name</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">#xs:integer</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $x := 23, $y := 93.7 
return atomic-type-annotation($x) ? matches($y)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">false()</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">atomic-type-annotation(xs:numeric('23.2')) ? name</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">#xs:double</eg></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-node-type-annotation"><head>fn:node-type-annotation</head><changes><change issue="148" PR="1523" date="2024-10-22">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Returns a record containing information about the type annotation of an element or attribute node.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="node-type-annotation" return-type-ref="schema-type-record" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="node" type="(element() | attribute())"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Given an element or attribute node, the function returns a <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#schema-type-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">schema-type-record</loc>
         containing information about the schema type represented by its <xtermref spec="DM40" ref="dt-type-annotation"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>For an element that has not been schema-validated, the type annotation is always <code nobreak="false">xs:untyped</code>.</p><p>For an attribute that has not been schema-validated, the type annotation is always <code nobreak="false">xs:untypedAtomic</code>.</p><p>The type annotation of an attribute node is always a simple type; the type annotation of an element node may
         be simple or complex.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $e := parse-xml("&lt;e/&gt;")/*
return node-type-annotation($e) ? name</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">#xs:untyped</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $a := parse-xml("&lt;e a='3'/&gt;")//@a
return node-type-annotation($a) ? name</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">#xs:untypedAtomic</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $x := json-to-xml('[23, 24]', { 'validate': true() })
return node-type-annotation($x/*) ? name</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">#fn:arrayType</eg></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $x := json-to-xml('[23, 24]', { 'validate': true() })
let $n23 := $x//fn:number[. = 23]                  
let $type := node-type-annotation($n23)
return ($type ? name, 
        $type ? base-type() ? name, 
        $type ? base-type() ? base-type() ? name)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">#fn:numberType, 
#fn:finiteNumberType, 
#xs:double</eg></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="context"><head>Accessing the context</head><p>The following functions are defined to obtain information from the 
            static or dynamic context.</p><table class="index"><thead><tr><th rowspan="1" colspan="1">Function</th><th rowspan="1" colspan="1">Meaning</th></tr></thead><tbody><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:current-date</code></td><td rowspan="1" colspan="1">Returns the current date.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:current-dateTime</code></td><td rowspan="1" colspan="1">Returns the current date and time (with timezone).</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:current-time</code></td><td rowspan="1" colspan="1">Returns the current time.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:default-collation</code></td><td rowspan="1" colspan="1">Returns the value of the default collation property from the <phrase diff="chg" at="2023-05-19">dynamic</phrase> context. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:default-language</code></td><td rowspan="1" colspan="1">Returns the value of the default language property from the dynamic context. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:implicit-timezone</code></td><td rowspan="1" colspan="1">Returns the value of the implicit timezone property from the dynamic context. </td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:last</code></td><td rowspan="1" colspan="1">Returns the context size from the dynamic context.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:position</code></td><td rowspan="1" colspan="1">Returns the context position from the dynamic context.</td></tr><tr><td style="white-space:nowrap; vertical-align:top" rowspan="1" colspan="1"><code style="padding-right: 10px" nobreak="false">fn:static-base-uri</code></td><td rowspan="1" colspan="1">This function returns the value of the <term>executable base URI</term> property from the dynamic
            context.</td></tr></tbody></table><div2 id="func-current-date"><head>fn:current-date</head><glist><gitem><label>Summary</label><def><p>Returns the current date.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="current-date" return-type="xs:date" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>Returns <code nobreak="false">xs:date(fn:current-dateTime())</code>. This is an <code nobreak="false">xs:date</code>
            (with timezone) that is current at some time during the evaluation of a query or
            transformation in which <function>fn:current-date</function> is executed.</p><p>This function is <termref def="dt-deterministic"/>. The precise instant during the query
            or transformation represented by the value of <function>fn:current-date</function> is <termref def="implementation-dependent">implementation-dependent</termref>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The returned date will always have an associated timezone, which will always be the same
            as the implicit timezone in the dynamic context</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">current-date()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>An <code nobreak="false">xs:date</code> corresponding to the
               current date. For example, a call of <code nobreak="false">current-date()</code> might return
                  <code nobreak="false">2004-05-12+01:00</code>.</p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-current-dateTime"><head>fn:current-dateTime</head><glist><gitem><label>Summary</label><def><p>Returns the current date and time (with timezone).</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="current-dateTime" return-type="xs:dateTimeStamp" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>Returns the current dateTime (with timezone) from the dynamic context. (See <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.) This is an
               <code nobreak="false">xs:dateTime</code> that is current at some time during the evaluation of a
            query or transformation in which <function>fn:current-dateTime</function> is executed.</p><p>This function is <termref def="dt-deterministic"/>. The precise instant during the query
            or transformation represented by the value of <code nobreak="false">fn:current-dateTime()</code> is
            <termref def="implementation-dependent">implementation-dependent</termref>.</p><p>If the implementation supports data types from XSD 1.1 then the returned value will be
            an instance of <code nobreak="false">xs:dateTimeStamp</code>. Otherwise, the only guarantees are that it
            will be an instance of <code nobreak="false">xs:dateTime</code> and will have a timezone component.</p></def></gitem><gitem><label>Notes</label><def><note><p>The returned <code nobreak="false">xs:dateTime</code> will always have an associated timezone, which
            will always be the same as the implicit timezone in the dynamic context</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">current-dateTime()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>An <code nobreak="false">xs:dateTimeStamp</code>
               corresponding to the current date and time. For example, a call of
                  <code nobreak="false">current-dateTime()</code> might return
                  <code nobreak="false">2024-05-12T18:17:15.125Z</code> corresponding to the current time on May 12,
               2024 in timezone <code nobreak="false">Z</code>. </p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-current-time"><head>fn:current-time</head><glist><gitem><label>Summary</label><def><p>Returns the current time.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="current-time" return-type="xs:time" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>Returns <code nobreak="false">xs:time(fn:current-dateTime())</code>. This is an <code nobreak="false">xs:time</code>
            (with timezone) that is current at some time during the evaluation of a query or
            transformation in which <function>fn:current-time</function> is executed.</p><p>This function is <termref def="dt-deterministic"/>. The precise instant during the query
            or transformation represented by the value of <code nobreak="false">fn:current-time()</code> is <termref def="implementation-dependent">implementation-dependent</termref>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The returned time will always have an associated timezone, which will always be the same
            as the implicit timezone in the dynamic context</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">current-time()</code></eg></td><td valign="top" rowspan="1" colspan="1"><p>An <code nobreak="false">xs:time</code> corresponding to the
               current time. For example, a call of <code nobreak="false">current-time()</code> might return
                  <code nobreak="false">23:17:00.000-05:00</code>.</p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-default-collation"><head>fn:default-collation</head><glist><gitem><label>Summary</label><def><p>Returns the value of the default collation property from the <phrase diff="chg" at="2023-05-19">dynamic</phrase> context. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="default-collation" return-type="xs:string" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		collations.
	</p></def></gitem><gitem><label>Rules</label><def><p>Returns the value of the default collation property from the 
            <phrase diff="chg" at="2023-05-19">dynamic</phrase> context context. Components
            of the dynamic context are described in <xspecref spec="XP40" ref="eval_context"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The default collation property can never be absent. If it is not explicitly defined, a
            system defined default can be invoked. If this is not provided, the Unicode codepoint
            collation (<code nobreak="false">http://www.w3.org/2005/xpath-functions/collation/codepoint</code>) is
            used. </p><p diff="add" at="2023-05-19">In most cases, the default collation is known statically,
         and a call on this function can therefore be pre-evaluated during static analysis. The only
         notable exception is when a call on <code nobreak="false">default-collation()</code> is used to define
         the default value of a parameter to a user-defined function. In this case it is interpreted
         as a reference to the default collation in the context of the relevant function call,
         which may differ from the default collation of the function definition.</p></note></def></gitem></glist></div2><div2 id="func-default-language"><head>fn:default-language</head><glist><gitem><label>Summary</label><def><p>Returns the value of the default language property from the dynamic context. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="default-language" return-type="xs:language" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		default language.
	</p></def></gitem><gitem><label>Rules</label><def><p>Returns the value of the default language property from the dynamic context. Components
            of the dynamic context are described in <xspecref spec="XP40" ref="eval_context"/>.</p></def></gitem><gitem><label>Notes</label><def><note><p>The default language property can never be absent. The functions <function>fn:format-integer</function>,
         <function>fn:format-date</function>, <function>fn:format-time</function>, and <function>fn:format-dateTime</function>
         are defined to use the default language if no explicit language is supplied. The default language
         may play a role in selection of a default collation, but this is not a requirement.</p></note></def></gitem></glist></div2><div2 id="func-implicit-timezone"><head>fn:implicit-timezone</head><glist><gitem><label>Summary</label><def><p>Returns the value of the implicit timezone property from the dynamic context. </p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="implicit-timezone" return-type="xs:dayTimeDuration" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		implicit timezone.
	</p></def></gitem><gitem><label>Rules</label><def><p>Returns the value of the implicit timezone property from the dynamic context. Components
            of the dynamic context are described in <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.</p></def></gitem></glist></div2><div2 id="func-last"><head>fn:last</head><glist><gitem><label>Summary</label><def><p>Returns the context size from the dynamic context.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="last" return-type="xs:integer" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Returns the context size from the dynamic context. (See <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.)</p></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> if
            the context <phrase>size</phrase> is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p></def></gitem><gitem><label>Notes</label><def><note><p>Under most circumstances, the context size is absent only if the context value is absent. However, XSLT 3.0 with
         streaming defines situations in which the context value and context position are known, but the context size is unknown.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><thead><tr><th rowspan="1" colspan="1">Expression</th><th rowspan="1" colspan="1">Result</th></tr></thead><tbody><tr><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve"><code nobreak="false">(1 to 20)[last() - 1]</code></eg></td><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">19</code></p></td></tr></tbody></table></def></gitem></glist></div2><div2 id="func-position"><head>fn:position</head><glist><gitem><label>Summary</label><def><p>Returns the context position from the dynamic context.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="position" return-type="xs:integer" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-dependent">focus-dependent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Returns the context position from the dynamic context. (See <xspecref spec="XP40" ref="id-xp-evaluation-context-components"/>.)</p></def></gitem><gitem><label>Error Conditions</label><def><p>A type error is raised <xerrorref spec="XP" class="DY" code="0002" type="type"/> if
            the context value is <xtermref ref="dt-absent" spec="DM40">absent</xtermref>.</p></def></gitem></glist></div2><div2 id="func-static-base-uri"><head>fn:static-base-uri</head><glist><gitem><label>Summary</label><def><p diff="chg" at="2023-05-19">This function returns the value of the <term>executable base URI</term> property from the dynamic
            context.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="static-base-uri" return-type="xs:anyURI?" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"/></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-dependent">context-dependent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>.  It depends on 
		executable base URI.
	</p></def></gitem><gitem><label>Rules</label><def><p diff="chg" at="2023-05-19">The function (despite its name) 
            returns the value of the <term>executable base URI</term> property from the dynamic context.
            If the property is absent, the empty sequence is returned.</p><p diff="chg" at="2023-05-19">Components of the dynamic context are described in <xspecref spec="XP40" ref="eval_context"/> .</p></def></gitem><gitem><label>Notes</label><def><note><p>The executable base URI will in many cases be the same as the static base URI in the static context.
            However, XQuery and XSLT give an implementation freedom to use different base URIs during
            the static analysis phase and the dynamic evaluation phase, that is, for retrieval of compile-time
            and run-time resources respectively. This is appropriate when the implementation allows
            the output of static analysis (a “compiled” query or stylesheet) to be deployed for execution
            to a different location from the one where static analysis took place. In this situation, the
               <function>fn:static-base-uri</function> function should return a URI suitable for locating
            resources needed during dynamic evaluation.</p><p>If a call on the <function>fn:static-base-uri</function> function appears within the expression used
         to define the value of an optional parameter to a user-defined function, then the value supplied
         to the function (if the argument is omitted) will be the executable base URI from the dynamic
         context of the function caller. This allows such a function to resolve relative URIs supplied
         in other parameters to the same function.</p></note></def></gitem></glist></div2></div1><div1 id="errors-and-diagnostics"><head>Errors and diagnostics</head><div2 id="errors"><head>Raising errors</head><p>In this document, as well as in <bibref ref="xquery-40"/> and <bibref ref="xpath-40"/>,
	            the phrase <quote>an error is raised</quote>
	                is used. Raising an error is equivalent to calling the <function>fn:error</function>
	                function defined in this section with the provided error code. Except where otherwise
	                specified, errors defined in this specification are dynamic errors. Some errors,
	                however, are classified as type errors. Type errors are typically used where the presence
	         of the error can be inferred from knowledge of the type of the actual arguments to a function, for
	         example with a call such as <code nobreak="false">fn:string(fn:abs#1)</code>. Host languages may allow type errors
	         to be reported statically if they are discovered during static analysis.</p><p> When function specifications indicate that an error is to be raised, the notation 
	            <quote>[<emph>error code</emph>]</quote> is used to specify an error code. Each error defined
	                in this document is identified by an <code nobreak="false">xs:QName</code> that is in the
	                <code nobreak="false">http://www.w3.org/2005/xqt-errors</code> namespace, represented in this document by the <code nobreak="false">err</code> prefix. It is this
	                <code nobreak="false">xs:QName</code> that is actually passed as an argument to the
	                <function>fn:error</function> function. Calling this function raises an error.  For a
	                more detailed treatment of error handing, see <xspecref spec="XP40" ref="id-handling-dynamic"/>.</p><p>The <function>fn:error</function> function is a general function that may be called as above
	                but may also be called from <bibref ref="xquery-40"/> or <bibref ref="xpath-40"/>
	                applications with, for example, an <code nobreak="false">xs:QName</code> argument. </p><div3 id="func-error"><head>fn:error</head><changes><change issue="895" PR="901" date="2023-12-16">All three arguments are now optional, and each argument can be set
            to the empty sequence. Previously if <code nobreak="false">$description</code> was supplied, it could not be empty.</change></changes><glist><gitem><label>Summary</label><def><p>Calling the <function>fn:error</function> function raises an application-defined error.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="error" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="code" type="xs:QName?" default="()"/><arg name="description" type="xs:string?" default="()"/><arg name="value" type="item()*" default="."/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-nondeterministic">nondeterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>This function never returns a value. Instead it always raises an error. The effect of
            the error is identical to the effect of dynamic errors raised implicitly, for example
            when an incorrect argument is supplied to a function.</p><p>The parameters to the <function>fn:error</function> function supply information that is
            associated with the error condition and that is made available to a caller that asks for
            information about the error. The error may be caught either by the host language (using
            a try/catch construct in XSLT or XQuery, for example), or by the calling application or
            external processing environment. The way in which error information is returned to the
            external processing environment is <termref def="implementation-dependent">implementation-dependent</termref>.</p><p>There are three pieces of information that may be associated with an error.</p><ulist><item><p>The <code nobreak="false">$code</code> is an error code that distinguishes this error from others.
                  It is an <code nobreak="false">xs:QName</code>; the namespace URI conventionally identifies the
                  component, subsystem, or authority responsible for defining the meaning of the
                  error code, while the local part identifies the specific error condition. The
                  namespace URI <code nobreak="false">http://www.w3.org/2005/xqt-errors</code> is used for errors
                  defined in this specification; other namespace URIs may be used for errors defined
                  by the application.</p><p>If the external processing environment expects the error code to be returned as a
                  URI or a string rather than as an <code nobreak="false">xs:QName</code>, then an error code with
                  namespace URI <code nobreak="false">NS</code> and local part <code nobreak="false">LP</code> will be returned in
                  the form <code nobreak="false">NS#LP</code>. The namespace URI part of the error code should
                  therefore not include a fragment identifier.</p><p>If <code nobreak="false">$code</code> is the empty sequence, the effective value of the error code
                  is <code nobreak="false">fn:QName('http://www.w3.org/2005/xqt-errors', 'err:FOER0000')</code>.</p></item><item><p>The <code nobreak="false">$description</code> is a natural-language description of the error
                  condition.</p><p>If the value is the empty sequence, then the effective value of the description is
                  <termref def="implementation-dependent">implementation-dependent</termref>.</p></item><item><p>The <code nobreak="false">$value</code> is an arbitrary value used to convey additional
                  information about the error, and may be used in any way the application
                  chooses.</p><p>If the value supplied is the empty sequence, then the effective value of the
                  error object is
                  <termref def="implementation-dependent">implementation-dependent</termref>.</p></item></ulist></def></gitem><gitem><label>Error Conditions</label><def><p>This function always raises a dynamic error. By default, it raises <errorref class="ER" code="0000"/></p></def></gitem><gitem><label>Notes</label><def><note><p>The value of the <code nobreak="false">$description</code> parameter may need to be localized.</p><p>Since the function never returns a value, the declared return type of <code nobreak="false">item()*</code>
            is a convenient fiction. It is relevant insofar as a function item such as <code nobreak="false">error#1</code>
            may (as a consequence of function coercion) be supplied in contexts where a function with a more specific
            return type is required.</p><p>Any QName may be used as an error code; there are no reserved names or namespaces. The
            error is always classified as a dynamic error, even if the error code used is one that
            is normally used for static errors or type errors.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><p><code nobreak="false">error()</code></p></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Raises error FOER0000.</p><p><emph>(This returns the URI
                     <code nobreak="false">http://www.w3.org/2005/xqt-errors#FOER0000</code> (or the corresponding
                     <code nobreak="false">xs:QName</code>) to the external processing environment, unless the error
                  is caught using a try/catch construct in the host language.)</emph></p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">error(
  QName('http://www.example.com/HR', 'myerr:toohighsal'),
  'Salary is too high'
)</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>Raises error myerr:toohighsal.</p><p><emph>(This returns <code nobreak="false">http://www.example.com/HR#toohighsal</code> and the
                     <code nobreak="false">xs:string</code>
                  <code nobreak="false">"Salary is too high"</code> (or the corresponding
                     <code nobreak="false">xs:QName</code>) to the external processing environment, unless the error
                  is caught using a try/catch construct in the host language.)</emph></p></td></tr></tbody></table></def></gitem></glist></div3></div2><div2 id="diagnostics"><head>Diagnostic tracing</head><div3 id="func-trace"><head>fn:trace</head><changes><change issue="895" PR="901" date="2023-12-16">The <code nobreak="false">$label</code> argument can now be set
            to the empty sequence. Previously if <code nobreak="false">$label</code> was supplied, it could not be empty.</change></changes><glist><gitem><label>Summary</label><def><p>Provides an execution trace intended to be used in debugging queries.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="trace" return-type="item()*" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="label" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>The function returns <code nobreak="false">$input</code>, unchanged.</p><p>In addition, the values of <code nobreak="false">$input</code>, typically serialized and converted
            to an <code nobreak="false">xs:string</code>, and <code nobreak="false">$label</code> (if non-empty) <rfc2119>may</rfc2119>
            be output to an <termref def="implementation-defined"/> destination.</p><p>Any serialization of the implementation’s trace output <rfc2119>must not</rfc2119> raise an error.
            This can be achieved (for example) by using a serialization method that can handle
            arbitrary input, such as the adaptive output method (see
            <xspecref spec="SER31" ref="adaptive-output"/>).</p><p>The format of the trace output and its order are
            <termref def="implementation-dependent"/>. Therefore, the order in which the output
            appears is not predictable. This also means that if dynamic errors occur
            (whether or not they are caught using try/catch), it may be unpredictable whether
            any output is reported before the error occurs.</p></def></gitem><gitem><label>Notes</label><def><note><p>If the trace information is unrelated to a specific value,
            <function>fn:message</function> can be used instead.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">let $v := 124.84
return fn:trace($v, 'the value of $v is: ')</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The function returns the <code nobreak="false">xs:decimal</code> value <code nobreak="false">124.84</code>,
               while outputting a message such as "the value of $v is: 124.84" to 
               an <termref def="implementation-defined"/> destination. The format of the message
               is also <termref def="implementation-defined"/>.</p></td></tr><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">//book[xs:decimal(@price) gt 100] 
    =&gt; trace('books more expensive than €100:')</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The result of the expression is the same as the result of
               <code nobreak="false">//book[xs:decimal(@price) gt 100]</code>, but evaluation has the side-effect of
               providing diagnostic feedback to the user.</p></td></tr></tbody></table></def></gitem></glist></div3><div3 id="func-message"><head>fn:message</head><changes><change issue="574 651" PR="629 803" date="2023-11-07">New in 4.0</change></changes><glist><gitem><label>Summary</label><def><p>Outputs trace information and discards the result.</p></def></gitem><gitem><label>Signature</label><def><example role="signature"><proto isOp="no" prefix="fn" name="message" return-type="empty-sequence()" returnEmptyOk="no" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isSpecial="no"><arg name="input" type="item()*"/><arg name="label" type="xs:string?" default="()"/></proto></example></def></gitem><gitem><label>Properties</label><def><p>This function is <termref def="dt-deterministic">deterministic</termref>, <termref def="dt-context-independent">context-independent</termref>,  and <termref def="dt-focus-independent">focus-independent</termref>. </p></def></gitem><gitem><label>Rules</label><def><p>Similar to <function>fn:trace</function>, the values of <code nobreak="false">$input</code>,
            typically serialized and converted to an <code nobreak="false">xs:string</code>, and <code nobreak="false">$label</code>
            (if non-empty) <rfc2119>may</rfc2119> be output to an
            <termref def="implementation-defined"/> destination.</p><p>In contrast to <function>fn:trace</function>, the function returns the empty sequence.</p><p>Any serialization of the implementation’s log output <rfc2119>must not</rfc2119> raise an error.
            This can e.g. be achieved by using a serialization method that can handle arbitrary
            input, such as the <xspecref spec="SER31" ref="adaptive-output"/>.</p><p>The format of the log output and its order are
            <termref def="implementation-dependent"/>. Therefore, the order in which the output
            appears is not predictable. This also means that if dynamic errors occur
            (whether or not they are caught using try/catch), it may be unpredictable whether
            any output is logged before the error occurs.</p></def></gitem><gitem><label>Notes</label><def><note><p>The function can be used for debugging. It can also be helpful in productive
            environments, e.g. to store dynamic input and evaluations to log files.</p></note></def></gitem><gitem><label>Examples</label><def role="example"><table role="medium"><tbody><tr class="testdiv"><th valign="top" rowspan="1" colspan="1">Expression:</th><td valign="top" rowspan="1" colspan="1"><eg xml:space="preserve">//book[if (xs:decimal(@price) lt 1000) 
                     then true() 
                     else message(@price, @title || ' is unexpectedly expensive: ')]</eg></td></tr><tr><th valign="top" rowspan="1" colspan="1">Result:</th><td valign="top" rowspan="1" colspan="1"><p>The result of the expression is the same as the result of
               <code nobreak="false">//book[xs:decimal(@price) lt 1000]</code>, but evaluation has the side-effect of
               providing diagnostic feedback to the user relating to books above this price threshold.</p></td></tr></tbody></table></def></gitem></glist></div3></div2></div1><div1 id="constructor-functions"><head>Constructor functions</head><changes><change issue="658" PR="662" date="2023-08-29">
                 Constructor functions now have a zero-arity form; the first
                 argument defaults to the context item.
              </change></changes><p>
              Constructor functions are used to convert a supplied value to a given type,
              and the name of the function is the same as the name of the target type. 
              This section describes constructor functions corresponding to the following types:</p><ulist><item><p>Simple types (atomic types, union types, and list types as
                 defined in <bibref ref="xmlschema-2"/>), which are present in the
                 static context either because they appear in the 
                 <xtermref ref="dt-is-types" spec="XP40">in-scope schema types</xtermref>
                 or because they appear as
                 <xtermref spec="XP40" ref="dt-named-item-type">named item types</xtermref>.
              </p><p>These constructor functions always take a single argument.</p></item><item><p>Record types defined as 
                 <xtermref spec="XP40" ref="dt-named-item-type">named item types</xtermref>.</p><p>These take one argument for each named field of the record type.
              Constructor functions for record types are defined in 
                 <specref ref="id-constructors-for-record-tests"/>.
              </p></item></ulist><p>
              Constructor functions are defined for all user-defined named simple types, and for most built-in atomic, list, 
              and union types. The only named simple types that have no constructor function are those that have no instances 
              other than instances of their derived types: specifically, <code nobreak="false">xs:anySimpleType</code>, <code nobreak="false">xs:anyAtomicType</code>, 
              and <code nobreak="false">xs:NOTATION</code>. 
           </p><div2 id="constructor-functions-for-xsd-types"><head>Constructor functions for XML Schema built-in atomic types</head><p>Every built-in atomic 
                   type that is defined in <bibref ref="xmlschema-2"/>,
                   except <code nobreak="false">xs:anyAtomicType</code> and <code nobreak="false">xs:NOTATION</code>, has an
                    associated constructor function. The type <code nobreak="false">xs:untypedAtomic</code>, defined
                    in <xspecref spec="DM31" ref="types"/> and the two derived types
                    <code nobreak="false">xs:yearMonthDuration</code> and <code nobreak="false">xs:dayTimeDuration</code> defined
                    in <xspecref spec="DM31" ref="types"/> also have associated constructor functions.
                Implementations <rfc2119>may</rfc2119> additionally provide
                a constructor functions for the datatype <code nobreak="false">xs:dateTimeStamp</code> introduced in <bibref ref="xmlschema11-2"/>.</p><p>
A constructor function is not defined for <code nobreak="false">xs:anyAtomicType</code> as there are no atomic items with type annotation <code nobreak="false">xs:anyAtomicType</code> at runtime, although this can be a statically inferred type.
A constructor function is not defined for <code nobreak="false">xs:NOTATION</code> since it is defined as an abstract type in <bibref ref="xmlschema-2"/>.  If the static context (See <xspecref spec="XP40" ref="static_context"/>) contains a type derived from
<code nobreak="false">xs:NOTATION</code> then a constructor function is defined for it.
See <specref ref="constructor-functions-for-user-defined-types"/>.
</p><p> 
The form of the constructor function for an atomic type
                    <emph>eg:TYPE</emph> is:</p><example role="signature"><proto name="TYPE" prefix="eg" return-type="eg:TYPE" role="example" returnEmptyOk="yes" isSpecial="yes" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isOp="no"><arg name="value" type="xs:anyAtomicType?" default="."/></proto></example><p>If <code nobreak="false">$arg</code> is the empty sequence, the empty sequence is returned. For
                    example, the signature of the constructor function corresponding to the
                    <code nobreak="false">xs:unsignedInt</code> type defined in <bibref ref="xmlschema-2"/> is:</p><example role="signature"><proto name="unsignedInt" return-type="xs:unsignedInt" isSchema="yes" prefix="xs" returnEmptyOk="yes" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="arg" type="xs:anyAtomicType?" default="."/></proto></example><p>Calling the constructor function <code nobreak="false">xs:unsignedInt(12)</code> returns
                    the <code nobreak="false"> xs:unsignedInt</code> value 12. Another call of that constructor
                    function that returns the same <code nobreak="false">xs:unsignedInt</code> value is
                    <code nobreak="false">xs:unsignedInt("12")</code>.</p><p>The same result would also be returned if the
                    constructor function were to be called with a node that had a typed value equal
                    to the <code nobreak="false">xs:unsignedInt</code> 12.
                  Because the declared parameter type for the argument is <code nobreak="false">xs:anyAtomicType?</code>,
                  the coercion rules will atomize the supplied argument 
                        (see <xspecref spec="XP40" ref="id-atomization"/>) to
                    extract its typed value and then call the constructor with the atomized value.</p><p>If the value passed to a constructor function, after atomization, is not in the lexical space 
                  of the datatype to be constructed, 
                    and cannot be converted to a value in the value space of the datatype under the rules in
                    <specref ref="casting"/>, then an
                   dynamic error is raised <errorref class="RG" code="0001"/>.</p><p>The semantics of the constructor function 
                        <code nobreak="false">xs:TYPE(arg)</code>
                     are identical to the semantics of 
                        <code nobreak="false">arg</code> cast as <code nobreak="false">xs:TYPE?</code>
                    . See <specref ref="casting"/>.</p><p>If the argument to a constructor function is a literal, the result of the
                    function <rfc2119>may</rfc2119> be evaluated statically; if an error is found during such
                    evaluation, it may be reported as a static error. </p><p>Special rules apply to constructor functions for <code nobreak="false">xs:QName</code> and types derived from <code nobreak="false">xs:QName</code> and <code nobreak="false">xs:NOTATION</code>. See 
<specref ref="constructor-qname-notation"/>.
</p><p diff="add" at="Issue658">The argument is optional, and defaults to the context value (which
               will be atomized if necessary).</p><p>The following constructor functions for the built-in atomic types are supported:</p><ulist><item><proto name="string" return-type="xs:string" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="boolean" return-type="xs:boolean" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="decimal" return-type="xs:decimal" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="float" return-type="xs:float" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto><p>Implementations <rfc2119>should</rfc2119> return negative zero for <code nobreak="false">xs:float("-0.0E0")</code>.  
                           But because <bibref ref="xmlschema-2"/> does not distinguish between the values positive zero and negative zero,
                           implementations <rfc2119>may</rfc2119> return positive zero in this case.</p></item><item><proto name="double" return-type="xs:double" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto><p>Implementations <rfc2119>should</rfc2119> return negative zero for <code nobreak="false">xs:double("-0.0E0")</code>.  
                          But because <bibref ref="xmlschema-2"/> does not distinguish between the values positive zero and negative zero,
                          implementations <rfc2119>may</rfc2119> return positive zero in this case.</p></item><item><proto name="duration" return-type="xs:duration" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="dateTime" return-type="xs:dateTime" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="time" return-type="xs:time" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="date" return-type="xs:date" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="gYearMonth" return-type="xs:gYearMonth" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="gYear" return-type="xs:gYear" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="gMonthDay" return-type="xs:gMonthDay" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="gDay" return-type="xs:gDay" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="gMonth" return-type="xs:gMonth" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="hexBinary" return-type="xs:hexBinary" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="base64Binary" return-type="xs:base64Binary" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="anyURI" return-type="xs:anyURI" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="QName" return-type="xs:QName" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto><p>
                            See <specref ref="constructor-qname-notation"/> for special rules.</p></item></ulist><ulist><item><proto name="normalizedString" return-type="xs:normalizedString" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="token" return-type="xs:token" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="language" return-type="xs:language" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="NMTOKEN" return-type="xs:NMTOKEN" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="Name" return-type="xs:Name" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="NCName" return-type="xs:NCName" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="ID" return-type="xs:ID" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="IDREF" return-type="xs:IDREF" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="ENTITY" return-type="xs:ENTITY" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto><p>See <specref ref="casting-to-ENTITY"/> for rules related to constructing values of type <code nobreak="false">xs:ENTITY</code> and types derived from it.</p></item><item><proto name="integer" return-type="xs:integer" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="nonPositiveInteger" return-type="xs:nonPositiveInteger" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="negativeInteger" return-type="xs:negativeInteger" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="long" return-type="xs:long" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="int" return-type="xs:int" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="short" return-type="xs:short" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="byte" return-type="xs:byte" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="nonNegativeInteger" return-type="xs:nonNegativeInteger" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="unsignedLong" return-type="xs:unsignedLong" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="unsignedInt" return-type="xs:unsignedInt" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="unsignedShort" return-type="xs:unsignedShort" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="unsignedByte" return-type="xs:unsignedByte" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="positiveInteger" return-type="xs:positiveInteger" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item></ulist><ulist><item><proto name="yearMonthDuration" return-type="xs:yearMonthDuration" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="dayTimeDuration" return-type="xs:dayTimeDuration" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item><item><proto name="untypedAtomic" return-type="xs:untypedAtomic" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item></ulist><ulist><item><proto name="dateTimeStamp" return-type="xs:dateTimeStamp" returnEmptyOk="yes" isSchema="yes" prefix="xs" role="example" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto><p><emph>Available only if the implementation supports XSD 1.1.</emph></p></item></ulist></div2><div2 id="constructor-qname-notation"><head>Constructor functions for xs:QName and xs:NOTATION</head><p>Special rules apply to constructor functions for the types <code nobreak="false">xs:QName</code> and <code nobreak="false">xs:NOTATION</code>, for two reasons:</p><ulist><item><p>
Values cannot belong directly to the type <code nobreak="false">xs:NOTATION</code>, only to its subtypes.
</p></item><item><p>
The lexical representation of these types uses namespace prefixes, whose
meaning is context-dependent.</p></item></ulist><p>
These constraints result in the following rules:</p><olist><item><p>
There is no constructor function for <code nobreak="false">xs:NOTATION</code>. Constructors are defined, however, for <code nobreak="false">xs:QName</code>, 
   for types derived or constructed from <code nobreak="false">xs:QName</code>, and for types 
   derived or constructed from <code nobreak="false">xs:NOTATION</code>.
</p></item><item><p>When converting from an <code nobreak="false">xs:string</code>, the prefix within the lexical 
      <code nobreak="false">xs:QName</code> supplied
      as the argument is resolved to a namespace URI using the statically known
      namespaces from the static context. If the lexical <code nobreak="false">xs:QName</code>
      has no prefix, the
      namespace URI of the resulting expanded-QName is the default namespace for elements and types,
      taken from the static context. Components of the static context are
      defined in <xspecref spec="XP40" ref="static_context"/>. A dynamic error is raised <errorref class="NS" code="0004"/>
      if the prefix is not bound in the static context. As described in
      <xspecref spec="DM31" ref="terminology"/>, the supplied prefix is retained as part of the
      expanded-QName value.</p></item></olist><p>When a constructor function for a namespace-sensitive type is used as a literal function item
      or in a partial function application (for example, <code nobreak="false">xs:QName#1</code> or <code nobreak="false">xs:QName(?)</code>) the namespace
      bindings that are relevant are those from the static context of the literal function item or partial function application.
      When a constructor function for a namespace-sensitive type is obtained by means of the <function>fn:function-lookup</function>
      function, the relevant namespace bindings are those from the static context of the call on <function>fn:function-lookup</function>.</p><note><p>When the supplied argument to the <code nobreak="false">xs:QName</code> constructor
   function is a node, the node is atomized in the usual way, and if the result is <code nobreak="false">xs:untypedAtomic</code> it is then
   converted as if a string had been supplied. The effect might not be what is desired.
   For example, given the attribute <code nobreak="false">xsi:type="my:type"</code>, the expression 
   <code nobreak="false">xs:QName(@xsi:type)</code> might fail on the grounds that the prefix <code nobreak="false">my</code>
   is undeclared. This is because the namespace bindings are taken from the static context
   (that is, from the query or stylesheet), and not from the source document containing the
   <code nobreak="false">@xsi:type</code> attribute. The solution to this problem is to use the function call
   <code nobreak="false">resolve-QName(@xsi:type, .)</code> instead.</p></note></div2><div2 id="constructor-functions-for-xsd-list-types"><head>Constructor functions for XML Schema built-in list types</head><p>Each of the three built-in list
                 types defined in <bibref ref="xmlschema-2"/>,
                 namely <code nobreak="false">xs:NMTOKENS</code>, <code nobreak="false">xs:ENTITIES</code>, and <code nobreak="false">xs:IDREFS</code>, has an
                 associated constructor function.</p><p>The function signatures are as follows:</p><ulist><item><proto name="NMTOKENS" return-type="xs:NMTOKEN*" isSchema="yes" prefix="xs" role="example" returnEmptyOk="no" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:string?"/></proto></item><item><proto name="ENTITIES" return-type="xs:ENTITY*" isSchema="yes" prefix="xs" role="example" returnEmptyOk="no" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:string?"/></proto></item><item><proto name="IDREFS" return-type="xs:IDREF*" isSchema="yes" prefix="xs" role="example" returnEmptyOk="no" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:string?"/></proto></item></ulist><p>The semantics are equivalent to casting to the corresponding types from <code nobreak="false">xs:string</code>.</p><p>All three of these types have the facet <code nobreak="false">minLength = 1</code> meaning that there must
              always be at least one item in the list. The return type, however, allows for the fact that when the argument to
              the function is the empty sequence, the result is the empty sequence.</p><note><p>In the case of atomic types, it is possible to use an expression such as 
                 <code nobreak="false">xs:date(@date-of-birth)</code> to convert an attribute value to an instance of <code nobreak="false">xs:date</code>,
                 knowing that this will work both in the case where the attribute is already annotated as <code nobreak="false">xs:date</code>,
                 and also in the case where it is <code nobreak="false">xs:untypedAtomic</code>. This approach does not work with list types,
                 because it is not permitted to use a value of type <code nobreak="false">xs:NMTOKEN*</code> as input to the constructor
                 function <code nobreak="false">xs:NMTOKENS</code>. Instead, it is necessary to use conditional logic that performs the conversion
                 only in the case where the input is untyped: 
                 <code nobreak="false">if (@x instance of attribute(*, xs:untypedAtomic)) then xs:NMTOKENS(@x) else data(@x)</code></p></note></div2><div2 id="constructor-functions-for-xsd-union-types"><head>Constructor functions for XML Schema built-in union types</head><p>There is a constructor function for the union type <code nobreak="false">xs:numeric</code>
                 defined in <bibref ref="xpath-datamodel-40"/>. The function signature is:</p><ulist><item><proto name="numeric" return-type="xs:numeric?" isSchema="yes" prefix="xs" role="example" returnEmptyOk="no" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item></ulist><p>The semantics are determined by the rules in <specref ref="casting-to-union"/>. These rules have the effect that: </p><olist><item><p>If the argument is an instance of <code nobreak="false">xs:double</code>, <code nobreak="false">xs:float</code>, or <code nobreak="false">xs:decimal</code>,
                 then the result is an instance of the same primitive type, with the same value;</p></item><item><p>If the argument is an instance of <code nobreak="false">xs:boolean</code>, the result is the <code nobreak="false">xs:double</code> value
                    <code nobreak="false">0.0e0</code> or <code nobreak="false">1.0e0</code>;</p></item><item><p>If the argument is an instance of <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>, then:</p><olist><item><p>If the value is in the lexical space of <code nobreak="false">xs:double</code>, the result will be the
                       corresponding <code nobreak="false">xs:double</code> value;</p></item><item><p>Otherwise, a dynamic error <errorref class="RG" code="0001"/> occurs;</p></item></olist><note><p>The result will never be an instance of <code nobreak="false">xs:float</code>, <code nobreak="false">xs:decimal</code>,
                    or <code nobreak="false">xs:integer</code>. This is because <code nobreak="false">xs:double</code> appears first in the list of member
                    types of <code nobreak="false">xs:numeric</code>, and its lexical space subsumes the lexical space of the other numeric
                    types. Thus, unlike XPath numeric literals, the result does not depend on the lexical form of the supplied
                    value. The reason for this design choice is to retain compatibility with the function conversion rules:
                    functions such as <function>fn:abs</function> and <function>fn:round</function> are declared to expect an instance
                    of <code nobreak="false">xs:numeric</code> as their first or only argument, and compatibility with the function conversion
                    rules defined in earlier versions of these specifications demands that when an untyped atomic item
                    (or untyped node) is supplied as the argument, it is converted to an <code nobreak="false">xs:double</code> value
                       even if its lexical form is that (say) of an integer.</p></note></item><item><p>In all other cases, a dynamic error <errorref class="RG" code="0001"/> occurs.</p></item></olist><p>In the case of an implementation that supports XSD 1.1, there is a constructor function
              associated with the built-in union type <code nobreak="false">xs:error</code>.</p><p>The function signature is as follows:</p><ulist><item><proto name="error" return-type="xs:error?" isSchema="yes" prefix="xs" role="example" returnEmptyOk="no" returnSeq="no" returnVaries="no" isDatatype="no" isSpecial="no" isOp="no"><arg name="value" default="." type="xs:anyAtomicType?"/></proto></item></ulist><p>The semantics are equivalent to casting to the corresponding union type (see <specref ref="casting-to-union"/>).</p><note><p>Because <code nobreak="false">xs:error</code> has no member types, and therefore has an empty value space, casting
              will always fail with a dynamic error except in the case where the supplied argument is the empty
              sequence, in which case the result is also the empty sequence.</p></note></div2><div2 id="constructor-functions-for-user-defined-types"><head>Constructor functions for user-defined atomic and union types</head><p>For every <phrase diff="add" at="issue687">named</phrase> 
                   user-defined simple type in the static context (See <xspecref spec="XP40" ref="static_context"/>), there is a
                   constructor function whose name is the same as the name of the 
                   type<phrase diff="del" at="issue687">and whose
                    effect is to create a value of that type from the supplied argument. The rules
                    for constructing user-defined types are defined in the same way as the rules for
                    constructing built-in derived types defined in <specref ref="constructor-functions-for-xsd-types"/></phrase>.</p><p diff="add" at="issue687">For named atomic types, the rules
                  are the same as the rules for constructing built-in derived atomic types defined in <specref ref="constructor-functions-for-xsd-types"/>. For a named atomic type <code nobreak="false">T</code>,
               the signature of the function takes the form <code nobreak="false">T($value as xs:anyAtomicType? := .) as T?</code>,
                  and the semantics are the same as casting to derived types: see <specref ref="casting-to-derived-types"/>..</p><p diff="add" at="issue687">For named union types, the rules
                  follow the same principles as the rules for constructing built-in union types defined in <specref ref="constructor-functions-for-xsd-union-types"/>. For a named union type <code nobreak="false">U</code>,
                  the signature of the function takes the form <code nobreak="false">U($value as xs:anyAtomicType? := .) as U?</code>,
                  and the semantics are the same as casting to union types: see <specref ref="casting-to-union"/>.</p><p diff="add" at="issue687">For named list types, the rules
                  follow the same principles as the rules for constructing built-in list types defined in <specref ref="constructor-functions-for-xsd-list-types"/>. For a named list type <code nobreak="false">L</code>,
                  where the item type of <code nobreak="false">L</code> is <code nobreak="false">I</code>,
                  the signature of the function takes the form <code nobreak="false">L($value as xs:string? := .) as I*</code>,
                  and the semantics are the same as casting to list types: see <specref ref="casting-to-list"/>.</p><p diff="add" at="issue687">Constructor functions are available both for named types defined in an imported schema (that is,
                  named simple types in the <xtermref ref="dt-is-types" spec="XP40">in-scope schema types</xtermref>), 
                  and for types defined by means of <xtermref ref="dt-named-item-type" spec="XP40">named item types</xtermref>.
                  Specifically, named enumeration types follow the same rules as schema types derived by
                  restricting <code nobreak="false">xs:string</code>, and named local union types follow the same rules as
                  union types defined in a schema.</p><p>Special rules apply to constructor functions for namespace-sensitive types, that is,
                            atomic types derived from <code nobreak="false">xs:QName</code> and <code nobreak="false">xs:NOTATION</code>, list types that have
   a namespace-sensitive item type, and union types that have a namespace-sensitive member type. See <specref ref="constructor-qname-notation"/>.</p><example><head>Using a Constructor Function for a User-Defined Atomic Type</head><p>Consider a situation where the static context contains an atomic type
                    called <code nobreak="false">hatSize</code> defined in a schema whose target namespace is bound
                    to the prefix <code nobreak="false">eg</code>. In such a case the following constructor function is available to users:</p><example role="signature"><proto prefix="eg" name="hatSize" return-type="my:hatSize" isSpecial="yes" returnEmptyOk="yes" role="example" returnSeq="no" returnVaries="no" isSchema="no" isDatatype="no" isOp="no"><arg name="value" type="xs:anyAtomicType" emptyOk="yes"/></proto></example><p>The resulting function may be used in an expression such as <code nobreak="false">eg:hatSize("10½")</code>.</p></example><p diff="del" at="issue687">In the case of an atomic type <var>A</var>, the return type of the function is <code nobreak="false">A?</code>, reflecting
               the fact that the result will be the empty sequence if the input is the empty sequence. For a union or list type,
               the return type of the function is specified only as <code nobreak="false">xs:anyAtomicType*</code>. Implementations performing
               static type checking will often be able to compute a more specific result type. For example, if the target type
               is a list type whose item type is the atomic type <var>A</var>, the result will always be an instance of <var>A*</var>;
               if the target type is a pure union type <var>U</var> then the result will always be an instance of <var>U?</var>.
               In general, however, applications needing interoperable behavior on implementations that do strict static type
               checking will need to use a <code nobreak="false">treat as</code> expression to assert the specific type of the result.</p><note><p> To construct an instance of a user-defined type 
                  that is not in a namespace, it is possible to use an
                  <code nobreak="false">EQName</code> (for example <code nobreak="false">Q{}hatsize(17)</code>). Alternatives are
                    to use a cast expression (<code nobreak="false">17 cast as hatsize</code>) or (if the host language allows it) 
                  to undeclare the default function namespace. </p></note></div2><div2 diff="add" at="issue617" id="id-constructors-for-record-tests"><head>Constructor functions for named record types</head><changes><change issue="617" PR="953" date="2024-02-20">
                    Constructor functions for named record types have been introduced.
                 </change></changes><p>Both XQuery 4.0 and XSLT 4.0 provide syntax to declare named record types;
                 such a declaration implicitly adds a constructor function for values of that
                 type to the (See <xspecref spec="XP40" ref="static_context"/>).</p><p>For example, if there is a named item type with the XQuery definition:</p><eg xml:space="preserve">declare record my:location (
  latitude  as xs:double,
  longitude as xs:double
)</eg><p>then there will be a function definition equivalent to:</p><eg xml:space="preserve">declare function my:location (
  $latitude  as xs:double,
  $longitude as xs:double
) as my:location {
  { 'latitude': $latitude, 'longitude': $longitude }
}</eg><p>Equivalently using XSLT syntax, if there is a named item type with the
              XSLT definition:</p><eg xml:space="preserve">&lt;xsl:record name="my:location"
  as="record(latitude as xs:double, longitude as xs:double)"/&gt;</eg><p>then there will be a function definition equivalent to:</p><eg xml:space="preserve">&lt;xsl:function name="my:location" as="my:location"&gt;
  &lt;xsl:param name="latitude" as="xs:double"/&gt;
  &lt;xsl:param name="longitude" as="xs:double"/&gt;
  &lt;xsl:map&gt;
    &lt;xsl:map-entry key="'latitude'" select="$latitude"/&gt;
    &lt;xsl:map-entry key="'longitude'" select="$longitude"/&gt;
  &lt;/xsl:map&gt;
&lt;/xsl:function&gt;</eg><p>The rules defining the relationship of the function definition to the
              record type are given for XQuery 4.0 in <xspecref spec="XQ40" ref="named-records-as-functions"/>.</p><ednote><edtext>TODO: Add cross-reference to XSLT here. 
                 Anticipates resolution of issue #1485. </edtext></ednote></div2></div1><div1 id="casting"><head>Casting</head><p> Constructor functions and cast expressions accept an expression and return a value
                of a given type. They both convert a source value <var>SV</var>, of a source type,
                <var>ST</var> to a target value <var>TV</var>, of the given target type
                <var>TT</var>.</p><p>Constructor functions and cast expressions have identical semantics 
                but different syntax. The name of the
                constructor function is the same as the name of the built-in <bibref ref="xmlschema-2"/> 
                datatype or the datatype defined in <xspecref spec="DM31" ref="types"/>
                   of <bibref ref="xpath-datamodel-40"/> (see <specref ref="constructor-functions-for-xsd-types"/>) or the user-derived datatype
                (see <specref ref="constructor-functions-for-user-defined-types"/>) that is the
                target for the conversion, and the semantics are exactly the same as for a cast
                expression; for example,
                    <code nobreak="false">xs:date("2003-01-01")</code>
                 means exactly the same as 
                    <code nobreak="false">"2003-01-01"</code> cast as <code nobreak="false">xs:date?</code>.</p><p>The cast expression takes a type name to indicate the target type of the conversion.
                See <xspecref spec="XP40" ref="id-cast"/>. If the type name allows the empty sequence
                and the expression to be cast is the empty sequence, the empty sequence is returned.
                If the type name does not allow the empty sequence and the expression to be cast is
                the empty sequence, a type error is raised <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p><p>Where the argument to a cast is a literal, the result of the function <rfc2119>may</rfc2119> be
                evaluated statically; if an error is encountered during such evaluation, it <rfc2119>may</rfc2119> be
                reported as a static error. </p><p>The general rules for casting from primitive types to primitive types are defined in
            <specref ref="casting-from-primitive-to-primitive"/>, and subsections describe the rules
            for specific target types.
            The general rules for casting from <code nobreak="false">xs:string</code> (and <code nobreak="false">xs:untypedAtomic</code>)
            follow in <specref ref="casting-from-strings"/>.
            Casting to non-primitive types, including atomic types derived by restriction,
            union types, and list types, is described in <specref ref="casting-non-primitive-types"/>.  
            Casting from derived types is defined in <specref ref="casting-from-derived-to-parent"/>, 
            <specref ref="casting-within-branch"/> and <specref ref="casting-across-hierarchy"/>.</p><p>Casting is not supported to or from <code nobreak="false">xs:anySimpleType</code>. 
                  Casting to <code nobreak="false">xs:anySimpleType</code> is not permitted and raises a static error:
                     <xerrorref spec="XP" class="ST" code="0080"/>.</p><p>Similarly, casting is not supported to or from <code nobreak="false">xs:anyAtomicType</code> and will raise 
               a static error: <xerrorref spec="XP" class="ST" code="0080"/>. There are no atomic items 
               with the type annotation <code nobreak="false">xs:anyAtomicType</code>, although this can be a 
               statically inferred type.</p><div2 id="casting-from-primitive-to-primitive"><head>Casting from primitive types to primitive types</head><changes><change issue="1401" PR="1409">
                  This section now uses the term <term>primitive type</term> 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 <code nobreak="false">xs:untypedAtomic</code>. The three types <code nobreak="false">xs:integer</code>,
                  <code nobreak="false">xs:dayTimeDuration</code>, and <code nobreak="false">xs:yearMonthDuration</code>, which have custom
                  casting rules but are not strictly-speaking primitive, are now handled in other subsections.
               </change></changes><p>This section defines casting between <termref def="dt-primitive-type">primitive types</termref>
               (specifically, the 19 primitive types defined in <bibref ref="xmlschema-2"/> plus <code nobreak="false">xs:untypedAtomic</code>.
                    
               The type conversions
                    that are supported between primitive atomic types are indicated in the table below;
                    casts between other (non-primitive) types are defined in terms of these primitives.</p><p>Where the target type <var>TT</var> is a primitive type, the result <var>TV</var> will always
            be an instance of <var>TT</var>. The result <rfc2119>may</rfc2119> also be an instance of a type derived
            from <var>TT</var>: for example casting an <code nobreak="false">xs:NCName</code> <var>SV</var> 
               to <code nobreak="false">xs:string</code> <rfc2119>may</rfc2119> return <var>SV</var> unchanged, with its
            original type annotation.</p><p>In this table, there is a
               row for each <termref def="dt-primitive-type">primitive type</termref> acting as the source of the conversion and
               there is a column for each <termref def="dt-primitive-type">primitive type</termref> acting as the target of the conversion. The
                    intersections of rows and columns contain one of three characters:</p><ulist><item><p><code nobreak="false">Y</code> indicates that a conversion from values of the type to which
                        the row applies to the type to which the column applies is supported;</p></item><item><p><code nobreak="false">N</code> indicates that there are no supported conversions from values
                    of the type to which the row applies to the type to which the column applies;</p></item><item><p><code nobreak="false">M</code> indicates that a conversion from values of the type to
                    which the row applies to the type to which the column applies may succeed for
                    some values in the value space and fail for others.</p></item></ulist><p>There is no row or column for <code nobreak="false">xs:untypedAtomic</code> because the casting rules are exactly the same
            as for <code nobreak="false">xs:string</code>. When casting from <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>
            the semantics in <specref ref="casting-from-strings"/> apply, regardless of target type.
         </p><p>
               <bibref ref="xmlschema-2"/> defines <code nobreak="false">xs:NOTATION</code> as an abstract type. 
               Thus, casting to <code nobreak="false">xs:NOTATION</code> from any other type including <code nobreak="false">xs:NOTATION</code>
               is not permitted and raises a static error <xerrorref spec="XP" class="ST" code="0080"/>.  
               However, casting from one subtype of <code nobreak="false">xs:NOTATION</code> to another subtype of 
               <code nobreak="false">xs:NOTATION</code> is permitted.</p><p>Casting is not supported to or from <code nobreak="false">xs:anySimpleType</code>. Thus, there is no row
               or column for this type in the table below. For any node that has not been validated or 
               has been validated as <code nobreak="false">xs:anySimpleType</code>, the typed value of the node is an 
               atomic item of type <code nobreak="false">xs:untypedAtomic</code>. There are no atomic items with the 
               type annotation <code nobreak="false">xs:anySimpleType</code> at runtime. 
                  Casting to
                     <code nobreak="false">xs:anySimpleType</code> is not permitted and raises a static error:
                     <xerrorref spec="XP" class="ST" code="0080"/>.</p><p>Similarly, casting is not supported to or from <code nobreak="false">xs:anyAtomicType</code> and will raise 
               a static error: <xerrorref spec="XP" class="ST" code="0080"/>. There are no atomic items 
               with the type annotation <code nobreak="false">xs:anyAtomicType</code> at runtime, although this can be a 
               statically inferred type.</p><p>If casting is attempted from an <emph>ST</emph> to a <emph>TT</emph> for which
                    casting is not supported, as defined in the table below, a type error is raised <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p><p>In the following table, the columns and rows are identified by short codes that
                    identify simple types as follows:</p><slist><sitem>aURI = xs:anyURI</sitem><sitem>b64 = xs:base64Binary</sitem><sitem>bool = xs:boolean</sitem><sitem>dat = xs:date</sitem><sitem>gDay = xs:gDay</sitem><sitem>dbl = xs:double</sitem><sitem>dec = xs:decimal</sitem><sitem>dT = xs:dateTime</sitem><sitem>dur = xs:duration</sitem><sitem>flt = xs:float</sitem><sitem>hxB = xs:hexBinary</sitem><sitem>gMD = xs:gMonthDay</sitem><sitem>gMon = xs:gMonth</sitem><sitem>NOT = xs:NOTATION</sitem><sitem>QN = xs:QName</sitem><sitem>str = xs:string</sitem><sitem>tim = xs:time</sitem><sitem>gYM = xs:gYearMonth</sitem><sitem>gYr = xs:gYear</sitem></slist><p>In the following table, the notation <quote>S\T</quote> indicates that the source
                    (<quote>S</quote>) of the conversion is indicated in the column below the
                    notation and that the target (<quote>T</quote>) is indicated in the row to the
                    right of the notation.</p><table border="1" cellpadding="1" role="casting" summary="Casting table" id="casting-to-primitives-table"><col width="5%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><col width="3%" span="1"/><thead><tr><th rowspan="1" colspan="1">S\T</th><th rowspan="1" colspan="1">str</th><th rowspan="1" colspan="1">flt</th><th rowspan="1" colspan="1">dbl</th><th rowspan="1" colspan="1">dec</th><th rowspan="1" colspan="1">dur</th><th rowspan="1" colspan="1">dT</th><th rowspan="1" colspan="1">tim</th><th rowspan="1" colspan="1">dat</th><th rowspan="1" colspan="1">gYM</th><th rowspan="1" colspan="1">gYr</th><th rowspan="1" colspan="1">gMD</th><th rowspan="1" colspan="1">gDay</th><th rowspan="1" colspan="1">gMon</th><th rowspan="1" colspan="1">bool</th><th rowspan="1" colspan="1">b64</th><th rowspan="1" colspan="1">hxB</th><th rowspan="1" colspan="1">aURI</th><th rowspan="1" colspan="1">QN</th><th rowspan="1" colspan="1">NOT</th></tr></thead><tbody><tr><th rowspan="1" colspan="1">str</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">M</td></tr><tr><th rowspan="1" colspan="1">flt</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">dbl</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">M</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">dec</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">dur</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">dT</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">tim</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">dat</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">gYM</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">gYr</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">gMD</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">gDay</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">gMon</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">bool</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">b64</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">hxB</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">aURI</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td></tr><tr><th rowspan="1" colspan="1">QN</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">M</td></tr><tr><th rowspan="1" colspan="1">NOT</th><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">N</td><td rowspan="1" colspan="1">Y</td><td rowspan="1" colspan="1">M</td></tr></tbody></table><div3 id="casting-to-untypedAtomic"><head>Casting to <code nobreak="false">xs:untypedAtomic</code></head><p>Any atomic item <var>SV</var> can be cast to <code nobreak="false">xs:untypedAtomic</code>.</p><p>The effect is the same as casting to <code nobreak="false">xs:string</code> (see <specref ref="casting-to-string"/>)
               and then returning the <code nobreak="false">xs:untypedAtomic</code> value comprising the same sequence of
               characters.</p></div3><div3 id="casting-to-string"><head>Casting to <code nobreak="false">xs:string</code></head><p>Any atomic item <var>SV</var> can be cast to <code nobreak="false">xs:string</code>.</p><p>The resulting <code nobreak="false">xs:string</code> value <var>TV</var> depends on
                        the source type <var>ST</var> as follows.</p><ulist><item><p>If <var>SV</var> is an instance of <code nobreak="false">xs:string</code>,
                        <var>TV</var> is an instance of <code nobreak="false">xs:string</code> comprising
                        the same sequence of characters as <var>SV</var>.</p><note><p>The implementation is free to return <var>SV</var> unchanged,
                     including its original type annotation.</p></note></item><item><p>If <var>SV</var> is an instance of <code nobreak="false">xs:anyURI</code>, the result <var>TV</var> is an instance
                        of <code nobreak="false">xs:string</code> comprising the same sequence of characters
                        as <var>SV</var>, but with a type annotation of <code nobreak="false">xs:anyURI</code>.
                       No escaping of special characters takes place.</p></item><item><p>If <var>SV</var> is an instance of <code nobreak="false">xs:QName</code> or <code nobreak="false">xs:NOTATION</code>:</p><ulist><item><p>if the qualified name
                           has a prefix, then <var>TV</var> is the concatenation of the prefix of <var>SV</var>, 
                 		  a single colon (:), and the local name of <var>SV</var>.</p></item><item><p>otherwise <var>TV</var> is the local name of <var>SV</var>.</p></item></ulist></item><item><p>If <var>SV</var> is an instance of <code nobreak="false">xs:numeric</code>, 
                        the rules in <specref ref="casting-numeric-to-string"/> apply.</p></item><item><p>If <var>SV</var> is an instance of <code nobreak="false">xs:dateTime</code>, <code nobreak="false">xs:date</code>
                                or <code nobreak="false">xs:time</code>, the rules in <specref ref="casting-date-time-to-string"/> apply.
                        
                     </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:duration</code>, or any subtype thereof including
                        <code nobreak="false">xs:yearMonthDuration</code> and <code nobreak="false">xs:dayTimeDuration</code>, then the rules
                        in <specref ref="casting-duration-to-string"/> apply.</p></item><item><p>In all other cases, <var>TV</var> is the <bibref ref="xmlschema-2"/>
                                canonical representation of <var>SV</var>. For datatypes that do
                                not have a canonical representation defined an <termref def="implementation-dependent"/> canonical representation may be used.</p></item></ulist><p>To cast as <code nobreak="false">xs:untypedAtomic</code> the value is cast as
                        <code nobreak="false">xs:string</code>, as described above, and the type annotation changed
                        to <code nobreak="false">xs:untypedAtomic</code>.</p><div4 id="casting-numeric-to-string"><head>Casting numeric values to <code nobreak="false">xs:string</code></head><p>The following rules apply when the source type <var>ST</var> is <code nobreak="false">xs:decimal</code>,
                  <code nobreak="false">xs:double</code>, or <code nobreak="false">xs:float</code>, or any subtype of these including
                  <code nobreak="false">xs:integer</code>.</p><olist><item><p>If <var>SV</var> is an instance of <code nobreak="false">xs:decimal</code>,
                              then the canonical representation of
                              <var>SV</var> is returned, as defined in <bibref ref="xmlschema11-2"/>.
                                 Specifically, see <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/datatypes.html#f-decimalCanmap" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">decimalCanonicalMap</loc>.</p><note><p>Unlike previous versions of this specification, no special
                              rule is given for the case where <var>SV</var> is an instance of
                              <code nobreak="false">xs:integer</code>. This is because the general rule for
                              <code nobreak="false">xs:decimal</code> gives the same result. The result 
                                 in this case will be a sequence of decimal digits in the range
                              <char>U+0030</char> to <char>U+0039</char>, optionally
                           preceded by a minus sign, with no leading zeroes. For example:
                              <code nobreak="false">42</code>, <code nobreak="false">-1</code>, <code nobreak="false">0</code>, or <code nobreak="false">1000000000</code>.</p></note><note><p>An <code nobreak="false">xs:decimal</code> that is equal to an integer is converted
                              to a string as if it were first cast to an <code nobreak="false">xs:integer</code>.
                              Specifically, there will be no decimal point and no fractional part.</p><p>If the value is not equal to an integer, then there will be a decimal
                              point and a fractional part, which will be a sequence of decimal digits
                              with no trailing zeroes. For example: <code nobreak="false">42.3</code>, <code nobreak="false">-1.5</code>, 
                                 or <code nobreak="false">0.00001</code>.</p></note></item><item><p> If <var>SV</var> is an instance of <code nobreak="false">xs:float</code> or
                                        <code nobreak="false">xs:double</code>, then:</p><olist><item><p>
                                    <var>TV</var> will be an <code nobreak="false">xs:string</code> in the lexical space 
                                    of <code nobreak="false">xs:double</code> or <code nobreak="false">xs:float</code> that when
                                    converted to an <code nobreak="false">xs:double</code> or <code nobreak="false">xs:float</code> under 
                                    the rules of <specref ref="casting-from-strings"/> produces
                                    a value that is equal to <var>SV</var>, or is <code nobreak="false">NaN</code> 
                                    if <var>SV</var> is <code nobreak="false">NaN</code>.
                                    In addition, <var>TV</var> must satisfy the constraints in the
                                    following sub-bullets.
											</p><olist><item><p>If <var>SV</var> has an absolute value that is
                                                greater than or equal to 0.000001 (one millionth)
                                                and less than 1000000 (one million), then the value
                                                is converted to an <code nobreak="false">xs:decimal</code> and the
                                                resulting <code nobreak="false">xs:decimal</code> is converted to an
                                                <code nobreak="false">xs:string</code> according to the rules above, as though using an 
                                                implementation of <code nobreak="false">xs:decimal</code> that imposes no limits on the
                                                <code nobreak="false">totalDigits</code> or
                                                <code nobreak="false">fractionDigits</code> facets.</p></item><item><p>If <var>SV</var> has the value positive or negative zero, <var>TV</var> 
                                          is <code nobreak="false">"0"</code> or <code nobreak="false">"-0"</code> respectively.</p></item><item><p>If <var>SV</var> is positive or negative infinity, 
                                          <var>TV</var> is the string <code nobreak="false">"INF"</code> or <code nobreak="false">"-INF"</code> respectively.
                                       </p></item><item><p>In other cases, the result consists of a mantissa, which has the lexical form
                                       of an <code nobreak="false">xs:decimal</code>, followed by the letter "E", followed by an exponent which has
                                       the lexical form of an <code nobreak="false">xs:integer</code>. Leading zeroes and "+" signs are prohibited
                                       in the exponent. For the mantissa, there must be a decimal point, and there must
                                       be exactly one digit before the decimal point, which must be non-zero. The  "+"
                                       sign is prohibited. There must be at least one digit after the decimal point.
                                       Apart from this mandatory digit, trailing zero digits are prohibited. 
                                       </p></item></olist></item></olist><note><p>The above rules allow more than one representation of the same value. 
                                 For example, the <code nobreak="false">xs:float</code> value whose exact decimal representation is 1.26743223E15
                                 might be represented by any of the strings <code nobreak="false">"1.26743223E15"</code>,
                                 <code nobreak="false">"1.26743222E15"</code> or <code nobreak="false">"1.26743224E15"</code> (inter alia).
                                 It is implementation-dependent which of these representations is chosen.</p></note></item></olist><note><p>The string representations of numeric values are backwards compatible
                            with XPath 1.0 except for the special values positive and negative
                            infinity, negative zero and values outside the range <code nobreak="false">1.0e-6</code> to <code nobreak="false">1.0e+6</code>.</p></note></div4><div4 id="casting-date-time-to-string"><head>Casting date/time values to <code nobreak="false">xs:string</code></head><changes><change issue="1401" PR="1409">
                        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.
                     </change></changes><p>If <var>SV</var> is an instance of <code nobreak="false">xs:dateTime</code>,
                     <code nobreak="false">xs:date</code>, <code nobreak="false">xs:time</code>, <code nobreak="false">xs:gYear</code>, 
                     <code nobreak="false">xs:gYearMonth</code>, <code nobreak="false">xs:gMonth</code>, <code nobreak="false">xs:gMonthDay</code>, or <code nobreak="false">xs:gDay</code>,
                     then <var>TV</var> is the 
                     canonical representation of <var>SV</var> as defined in <bibref ref="xmlschema11-2"/>.
                  </p><note><p>The result <var>TV</var> includes the original timezone if a timezone is present.</p><p>All these data types contain different combinations of the components year, month, day,
                     hour, minute, second, and timezone; all the components relevant to the data type (with 
                     the exception of the timezone) are output, and the results are concatenated together 
                     with suitable punctuation. Specifically:</p><olist><item><p>The <code nobreak="false">year</code> component is 
                        represented as a <code nobreak="false">xs:string</code> of four digits, or more if needed. A leading minus 
                        sign is present for BCE years.</p></item><item><p>The <code nobreak="false">month</code>, <code nobreak="false">day</code>, <code nobreak="false">hour</code> and <code nobreak="false">minute</code> 
                        components are represented as two digits (with a leading zero if needed).
                       For example, February is represented as <code nobreak="false">02</code>.</p><p>The hours component will never be <code nobreak="false">"24"</code>: midnight 
                        is always represented as <code nobreak="false">"00:00:00"</code>.</p></item><item><p>The <code nobreak="false">second</code> component is output using as a two-digit integer
                        if it is a whole number (for example, <code nobreak="false">30</code>, <code nobreak="false">05</code>, or <code nobreak="false">00</code>),
                        or if it is fractional, as two digits followed by a decimal point followed by as many digits as
                        are necessary, with no trailing zeroes (for example <code nobreak="false">30.5</code> or <code nobreak="false">00.001</code>). </p></item><item><p>The timezone component, if present, is 
                        cast to <code nobreak="false">xs:string</code> by applying the function <code nobreak="false">eg:convertTZtoString</code>
                     given in <specref ref="casting-to-datetimes"/>. Examples are <code nobreak="false">Z</code>, <code nobreak="false">+01:00</code>,
                     <code nobreak="false">-05:00</code>, or <code nobreak="false">+05:30</code>.</p></item></olist><p>.
                  </p></note></div4><div4 id="casting-duration-to-string"><head>Casting <code nobreak="false">xs:duration</code> values to <code nobreak="false">xs:string</code></head><changes><change issue="1401" PR="1409">
                        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.
                     </change></changes><p>If <var>SV</var> is an instance of <code nobreak="false">xs:duration</code> (including its subtypes
                     <code nobreak="false">xs:yearMonthDuration</code> and <code nobreak="false">xs:dayTimeDuration</code>), then <var>TV</var> is the 
                     canonical representation of <var>SV</var> as defined in <bibref ref="xmlschema11-2"/>.
                     Specifically, see <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="https://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/datatypes.html#f-durationCanMap" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">durationCanonicalMap</loc>.</p><note><p>The rules have the effect of normalizing the value so that the number of months is always
                     less than 12, the number of hours less than 24, and the number of minutes and seconds less 
                     than 60. Zero-valued components are omitted. Fractional seconds follow the same rules
                     as <code nobreak="false">xs:decimal</code>. For example, the duration <code nobreak="false">P15MT30H</code>
                     is represented as <code nobreak="false">P1Y3M1DT6H</code>. A zero-length duration is output as <code nobreak="false">PT0S</code>.</p></note><note><p>At the time of writing, the published XSD 1.1 recommendation contains 
                        cut-and-paste errors in the definition
                     of the <code nobreak="false">dayTimeDuration</code> canonical mapping. The binding of variable <var>s</var>
                     should be to <var>dt</var>'s <code nobreak="false">·seconds·</code> (not <code nobreak="false">·months·</code>) component, and the return 
                        expression given as <code nobreak="false">sgn &amp; 'P' &amp; ·duYearMonthCanonicalFragmentMap·(|s|)</code>
                     should read <code nobreak="false">sgn &amp; 'P' &amp; ·duDayTimeCanonicalFragmentMap·(|s|)</code></p><p>In reading these XSD formulations, be aware that <code nobreak="false">a &amp; b</code> represents
                        string concatenation, while <code nobreak="false">|s|</code> computes the absolute value of a number.</p></note></div4></div3><div3 id="casting-to-numerics"><head>Casting to numeric types</head><p>This section defines the rules for casting to the primitive numeric types <code nobreak="false">xs:float</code>,
               <code nobreak="false">xs:double</code>, and <code nobreak="false">xs:decimal</code>. Rules for casting to the derived type
               <code nobreak="false">xs:integer</code> are given in <specref ref="casting-to-integer"/>.</p><div4 id="casting-to-float"><head>Casting to xs:float</head><p>When a value of any simple type is cast as <code nobreak="false">xs:float</code>, the <code nobreak="false">xs:float</code>
                            <var>TV</var> is derived from the <var>ST</var> and the
                            <var>SV</var> as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:float</code>, then <var>TV</var>
                                    is <var>SV</var> and the conversion is complete.</p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:double</code>, then
                                    <var>TV</var> is obtained as follows: </p><ulist><item><p>if <var>SV</var> is the <code nobreak="false">xs:double</code> value
                                            <code nobreak="false">INF</code>, <code nobreak="false">-INF</code>, <code nobreak="false">NaN</code>,
                                            positive zero, or negative zero, then <var>TV</var> is
                                            the <code nobreak="false">xs:float</code> value <code nobreak="false">INF</code>,
                                            <code nobreak="false">-INF</code>, <code nobreak="false">NaN</code>, positive zero, or
                                            negative zero respectively.</p></item><item><p>otherwise, <var>SV</var> can be expressed in the form
                                                <code nobreak="false">m × 2^e</code> where the mantissa
                                            <code nobreak="false">m</code> and exponent <code nobreak="false">e</code> are signed
                                            <code nobreak="false">xs:integer</code>s whose value range is defined in
                                                <bibref ref="xmlschema-2"/>, and the following rules apply:</p><ulist><item><p>if <code nobreak="false">m</code> (the mantissa of
                                                  <var>SV</var>) is outside the permitted range
                                                  for the mantissa of an <code nobreak="false">xs:float</code>
                                                  value <code nobreak="false">(-2^24-1 to +2^24-1)</code>, then it
                                                  is divided by <code nobreak="false">2^N</code> where
                                                  <code nobreak="false">N</code> is the lowest positive
                                                  <code nobreak="false">xs:integer</code> that brings the result
                                                  of the division within the permitted range, and
                                                  the exponent <code nobreak="false">e</code> is increased by
                                                  <code nobreak="false">N</code>. This is integer division (in
                                                  effect, the binary value of the mantissa is
                                                  truncated on the right). Let <code nobreak="false">M</code> be
                                                  the mantissa and <code nobreak="false">E</code> the exponent
                                                  after this adjustment.</p></item><item><p>if <code nobreak="false">E</code> exceeds <code nobreak="false">104</code> (the
                                                  maximum exponent value in the value space of
                                                  <code nobreak="false">xs:float</code>) then <var>TV</var> is
                                                  the <code nobreak="false">xs:float</code> value <code nobreak="false">INF</code>
                                                  or <code nobreak="false">-INF</code> depending on the sign of <code nobreak="false">M</code>.</p></item><item><p>if <code nobreak="false">E</code> is less than <code nobreak="false">-149</code>
                                                  (the minimum exponent value in the value space
                                                  of <code nobreak="false">xs:float</code>) then <var>TV</var> is
                                                  the <code nobreak="false">xs:float</code> value positive or
                                                  negative zero depending on the sign of <code nobreak="false">M</code>
                                                </p></item><item><p>otherwise, <var>TV</var> is the
                                                  <code nobreak="false">xs:float</code> value <code nobreak="false">M × 2^E</code>.</p></item></ulist></item></ulist></item><item><p>If <var>ST</var> is <code nobreak="false">xs:decimal</code>, or
                                    <code nobreak="false">xs:integer</code>, then <var>TV</var> is <code nobreak="false">xs:float(</code>
                                    <var>SV</var>
                                    <code nobreak="false"> cast as xs:string)</code> and the conversion is complete.</p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:boolean</code>, <var>SV</var> is
                                    converted to <code nobreak="false">1.0E0</code> if <var>SV</var> is
                                    <code nobreak="false">true</code> and to <code nobreak="false">0.0E0</code> if <var>SV</var>
                                    is <code nobreak="false">false</code> and the conversion is complete.</p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                    or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>. 
                        </p><note><p>XSD 1.1 adds the value <code nobreak="false">+INF</code> to the lexical space,
                           as an alternative to <code nobreak="false">INF</code>. XSD 1.1 also adds negative zero
                           to the value space.</p></note></item></ulist><note><p>Implementations <rfc2119>should</rfc2119> return negative zero for <code nobreak="false">xs:float("-0.0E0")</code>.  
                        But because <bibref ref="xmlschema-2"/> does not distinguish between the values positive zero and negative zero.
                        Implementations <rfc2119>may</rfc2119> return positive zero in this case.</p></note></div4><div4 id="casting-to-double"><head>Casting to xs:double</head><p>When a value of any simple type is cast as <code nobreak="false">xs:double</code>, the
                            <code nobreak="false">xs:double</code> value <var>TV</var> is derived from the
                            <var>ST</var> and the <var>SV</var> as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:double</code>, then
                                    <var>TV</var> is <var>SV</var> and the conversion is complete.</p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:float</code> or a type derived
                                    from <code nobreak="false">xs:float</code>, then <var>TV</var> is obtained as follows:</p><ulist><item><p>if <var>SV</var> is the <code nobreak="false">xs:float</code> value
                                            <code nobreak="false">INF</code>, <code nobreak="false">-INF</code>, <code nobreak="false">NaN</code>,
                                            positive zero, or negative zero, then <var>TV</var> is
                                            the <code nobreak="false">xs:double</code> value <code nobreak="false">INF</code>,
                                            <code nobreak="false">-INF</code>, <code nobreak="false">NaN</code>, positive zero, or
                                            negative zero respectively. </p></item><item><p>otherwise, <var>SV</var> can be expressed in the form
                                                <code nobreak="false">m × 2^e</code> where the
                                            mantissa <code nobreak="false">m</code> and exponent <code nobreak="false">e</code> are
                                            signed <code nobreak="false">xs:integer</code> values whose value range
                                            is defined in <bibref ref="xmlschema-2"/>, and
                                            <var>TV</var> is the <code nobreak="false">xs:double</code> value
                                                <code nobreak="false">m × 2^e</code>. </p></item></ulist></item><item><p>If <var>ST</var> is <code nobreak="false">xs:decimal</code> or
                                    <code nobreak="false">xs:integer</code>, then <var>TV</var> is <code nobreak="false">xs:double(</code>
                                    <var>SV</var>
                                    <code nobreak="false"> cast as xs:string)</code> and the conversion is complete.</p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:boolean</code>, <var>SV</var> is
                                    converted to <code nobreak="false">1.0E0</code> if <var>SV</var> is
                                    <code nobreak="false">true</code> and to <code nobreak="false">0.0E0</code> if <var>SV</var>
                                    is <code nobreak="false">false</code> and the conversion is complete.</p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                    or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>.</p><note><p>XSD 1.1 adds the value <code nobreak="false">+INF</code> to the lexical space,
                        as an alternative to <code nobreak="false">INF</code>. XSD 1.1 also adds negative zero
                        to the value space.</p></note></item></ulist><note><p>Implementations <rfc2119>should</rfc2119> return negative zero for <code nobreak="false">xs:double("-0.0E0")</code>.  
                        But because <bibref ref="xmlschema-2"/> does not distinguish between the values positive zero and negative zero.
                        Implementations <rfc2119>may</rfc2119> return positive zero in this case.</p></note></div4><div4 id="casting-to-decimal"><head>Casting to xs:decimal</head><p>This section defines the rules for casting to the primitive type <code nobreak="false">xs:decimal</code>.
                     The rules are also invoked implicitly as part of the process of converting to types
                     derived from <code nobreak="false">xs:decimal</code>. There are special rules, however, if the
                     target type <var>TT</var> is <code nobreak="false">xs:integer</code>, or a type derived from
                     <code nobreak="false">xs:integer</code>: those rules are given in <specref ref="casting-to-integer"/>.</p><p>When the target type <var>TT</var> is <code nobreak="false">xs:decimal</code>, the
                            resulting <code nobreak="false">xs:decimal</code> value <var>TV</var> is derived from
                            <var>ST</var> and <var>SV</var> as follows: </p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:decimal</code> or a subtype thereof 
                           (including <code nobreak="false">xs:integer</code>), then
                                    the result <var>TV</var> has the same <termref def="dt-datum"/> as <var>SV</var>.
                           The type annotation <rfc2119>may</rfc2119> be <code nobreak="false">xs:decimal</code> or any
                           subtype of <code nobreak="false">xs:decimal</code> for which this is a valid instance, including
                           the original type <code nobreak="false">ST</code>.</p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:float</code> or
                                    <code nobreak="false">xs:double</code>, then <var>TV</var> is the
                                    <code nobreak="false">xs:decimal</code> value, within the set of
                                    <code nobreak="false">xs:decimal</code> values that the implementation is
                                    capable of representing, that is numerically closest to
                                    <var>SV</var>. If two values are equally close, then the one
                                    that is closest to zero is chosen. If <var>SV</var> is too
                                    large to be accommodated as an <code nobreak="false">xs:decimal</code>, (see
                                        <bibref ref="xmlschema-2"/> for <termref def="implementation-defined"/> limits on
                           numeric values) a dynamic error is raised <errorref class="CA" code="0001"/>. If <var>SV</var> is one of the special
                                    <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code> values
                           <code nobreak="false">NaN</code>, <code nobreak="false">INF</code>, or <code nobreak="false">-INF</code>, a dynamic
                                    error is raised <errorref class="CA" code="0002"/>.</p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:boolean</code>, the result <var>TV</var> is
                                    <code nobreak="false">1.0</code> if <var>SV</var> is
                                    <code nobreak="false">1</code> or <code nobreak="false">true</code> and to <code nobreak="false">0.0</code> if
                                    <var>SV</var> is <code nobreak="false">0</code> or <code nobreak="false">false</code>.
                        The type annotation of the result may be any subtype of <code nobreak="false">xs:decimal</code>
                        whose value space includes the integer values <code nobreak="false">0</code> and <code nobreak="false">1</code>.</p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                    or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>.</p></item></ulist></div4></div3><div3 id="casting-to-durations"><head>Casting to duration types</head><p>This section defines the rules for casting to the primitive duration type <code nobreak="false">xs:duration</code>. 
                  Rules for casting to the derived types
               <code nobreak="false">xs:yearMonthDuration</code> and <code nobreak="false">xs:dayTimeDuration</code> 
                  are given in <specref ref="casting-to-duration-subtypes"/>.</p><ulist><item><p>If the source value <var>SV</var> is an instance of <code nobreak="false">xs:duration</code>
                        (including instances of subtypes such as <code nobreak="false">xs:yearMonthDuration</code>
                        and <code nobreak="false">xs:dayTimeDuration</code>, then the datum of the result 
                        <var>TV</var> is the same as the datum of <var>SV</var>, and the
                       type annotation is <code nobreak="false">xs:duration</code> or any subtype thereof that
                       includes this datum in its value space (in particular, it <rfc2119>may</rfc2119>
                        be the same as the type annotation of <var>SV</var>).</p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>.</p></item></ulist></div3><div3 id="casting-to-datetimes"><head>Casting to date and time types</head><p>In several situations, casting to date and time types requires the extraction
                        of a component from <var>SV</var> or from the result of
                        <function>fn:current-dateTime</function> and converting it to an
                        <code nobreak="false">xs:string</code>. These conversions must follow certain rules. For
                        example, converting an <code nobreak="false">xs:integer</code> year value requires
                        converting to an <code nobreak="false">xs:string</code> with four or more characters, preceded
                        by a minus sign if the value is negative.</p><p>This document defines four functions to perform these conversions. These
                        functions are for illustrative purposes only and make no recommendations as
                        to style or efficiency.  References to these functions from the following text are not normative.</p><p>The arguments to these functions come from functions defined in this
                        document. Thus, the functions below assume that they are correct and do no
                        range checking on them.</p><eg xml:space="preserve">
declare function eg:convertYearToString($year as xs:integer) as xs:string {
  let $plusMinus := if ($year &gt;= 0) then "" else "-"
  let $yearString := abs($year) cast as xs:string
  let $length := string-length($yearString)
  return if ($length = 1) then concat($plusMinus, "000", $yearString)
         else if ($length = 2) then concat($plusMinus, "00", $yearString)
         else if ($length = 3) then concat($plusMinus, "0", $yearString)
         else concat($plusMinus, $yearString)
};</eg><eg xml:space="preserve">
declare function eg:convertTo2CharString($value as xs:integer) as xs:string {
  let $string := $value cast as xs:string
  return if (string-length($string) = 1) then concat("0", $string)
         else $string
};</eg><eg xml:space="preserve">
declare function eg:convertSecondsToString($seconds as xs:decimal) as xs:string {
  let $string := $seconds cast as xs:string
  let $intLength := string-length(($seconds cast as xs:integer) cast as xs:string)
  return if ($intLength = 1) then concat("0", $string)
         else $string
};</eg><eg xml:space="preserve">
declare function eg:convertTZtoString($tz as xs:dayTimeDuration?) as xs:string {
  if (empty($tz)) then ""
  else if ($tz eq xs:dayTimeDuration('PT0S')) then "Z"
  else let $tzh := hours-from-duration($tz)
       let $tzm := minutes-from-duration($tz)
       let $plusMinus := if ($tzh &gt;= 0) then "+" else "-"
       let $tzhString := eg:convertTo2CharString(abs($tzh))
       let $tzmString := eg:convertTo2CharString(abs($tzm))
       return concat($plusMinus, $tzhString, ":", $tzmString)
};</eg><p>Conversion from 
                  <termref def="dt-primitive-type">primitive types</termref> to date and time types follows the rules below.</p><olist><item><p>When a value of any primitive type is cast as
                                <code nobreak="false">xs:dateTime</code>, the <code nobreak="false">xs:dateTime</code> value
                                <var>TV</var> is derived from <var>ST</var> and <var>SV</var>
                                as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:dateTime</code>, then
                                        <var>TV</var> is <var>SV</var>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:date</code>, then let
                                        <emph>SYR</emph> be <code nobreak="false">eg:convertYearToString( year-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>, let <emph>SMO</emph> be
                                            <code nobreak="false">eg:convertTo2CharString( month-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>, let <emph>SDA</emph> be
                                            <code nobreak="false">eg:convertTo2CharString( day-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:dateTime( concat(</code>
                                        <emph>SYR</emph>
                                        <code nobreak="false">, '-', </code>
                                        <emph>SMO</emph>
                                        <code nobreak="false">, '-', </code>
                                        <emph>SDA</emph>
                                        <code nobreak="false">, 'T00:00:00 '</code>, <emph>STZ</emph>
                                        <code nobreak="false">) )</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code> or
                                        <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>.</p></item></ulist></item><item><p>When a value of any primitive type is cast as <code nobreak="false">xs:time</code>,
                                the <code nobreak="false">xs:time</code> value <var>TV</var> is derived from
                                <var>ST</var> and <var>SV</var> as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:time</code>, then
                                        <var>TV</var> is <var>SV</var>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:dateTime</code>, then
                                        <var>TV</var> is <code nobreak="false">xs:time( concat(
                                            eg:convertTo2CharString( hours-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">)), ':', eg:convertTo2CharString( minutes-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">)), ':', eg:convertSecondsToString( seconds-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">)), eg:convertTZtoString( timezone-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">)) ))</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                        or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>. </p></item></ulist></item><item><p>When a value of any primitive type is cast as <code nobreak="false">xs:date</code>,
                                the <code nobreak="false">xs:date</code> value <var>TV</var> is derived from
                                <var>ST</var> and <var>SV</var> as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:date</code>, then
                                        <var>TV</var> is <var>SV</var>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:dateTime</code>, then let
                                        <emph>SYR</emph> be <code nobreak="false">eg:convertYearToString( year-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>, let <emph>SMO</emph> be
                                            <code nobreak="false">eg:convertTo2CharString( month-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>, let <emph>SDA</emph> be
                                            <code nobreak="false">eg:convertTo2CharString( day-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be <code nobreak="false">eg:convertTZtoString(timezone-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:date( concat(</code>
                                        <emph>SYR</emph>
                                        <code nobreak="false">, '-', </code>
                                        <emph>SMO</emph>
                                        <code nobreak="false">, '-', </code>
                                        <emph>SDA</emph>, <emph>STZ</emph>
                                        <code nobreak="false">) )</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                        or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>. </p></item></ulist></item><item><p>When a value of any primitive type is cast as
                                <code nobreak="false">xs:gYearMonth</code>, the <code nobreak="false">xs:gYearMonth</code> value
                                <var>TV</var> is derived from <var>ST</var> and <var>SV</var>
                                as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:gYearMonth</code>, then
                                        <var>TV</var> is <var>SV</var>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:dateTime</code>, then let
                                        <emph>SYR</emph> be <code nobreak="false">eg:convertYearToString( year-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>, let <emph>SMO</emph> be
                                            <code nobreak="false">eg:convertTo2CharString( month-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gYearMonth( concat(</code>
                                        <emph>SYR</emph>
                                        <code nobreak="false">, '-', </code>
                                        <emph>SMO</emph>, <emph>STZ</emph>
                                        <code nobreak="false">) )</code>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:date</code>, then let
                                        <emph>SYR</emph> be <code nobreak="false">eg:convertYearToString( year-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>, let <emph>SMO</emph> be
                                            <code nobreak="false">eg:convertTo2CharString( month-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gYearMonth( concat(</code>
                                        <emph>SYR</emph>
                                        <code nobreak="false">, '-', </code>
                                        <emph>SMO</emph>, <emph>STZ</emph>
                                        <code nobreak="false">) )</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                        or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>. </p></item></ulist></item><item><p>When a value of any primitive type is cast as <code nobreak="false">xs:gYear</code>,
                                the <code nobreak="false">xs:gYear</code> value <var>TV</var> is derived from
                                <var>ST</var> and <var>SV</var> as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:gYear</code>, then
                                        <var>TV</var> is <var>SV</var>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:dateTime</code>, let
                                        <emph>SYR</emph> be <code nobreak="false">eg:convertYearToString( year-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gYear(concat(</code>
                                        <emph>SYR</emph>, <emph>STZ</emph>
                                        <code nobreak="false">))</code>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:date</code>, let
                                        <emph>SYR</emph> be <code nobreak="false">eg:convertYearToString( year-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gYear(concat(</code>
                                        <emph>SYR</emph>, <emph>STZ</emph>
                                        <code nobreak="false">))</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                        or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>. </p></item></ulist></item><item><p>When a value of any primitive type is cast as
                                <code nobreak="false">xs:gMonthDay</code>, the <code nobreak="false">xs:gMonthDay</code> value
                                <var>TV</var> is derived from <var>ST</var> and <var>SV</var>
                                as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:gMonthDay</code>, then
                                        <var>TV</var> is <var>SV</var>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:dateTime</code>, then let
                                        <emph>SMO</emph> be <code nobreak="false">eg:convertTo2CharString( month-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>, let <emph>SDA</emph> be
                                            <code nobreak="false">eg:convertTo2CharString( day-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gYearMonth( concat(</code>
                                        <code nobreak="false"> '--', </code>
                                        <emph>SMO</emph>
                                        <code nobreak="false"> '-', </code>
                                        <emph>SDA</emph>, <emph>STZ</emph>
                                        <code nobreak="false">) )</code>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:date</code>, then let
                                        <emph>SMO</emph> be <code nobreak="false">eg:convertTo2CharString( month-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>, let <emph>SDA</emph> be
                                            <code nobreak="false">eg:convertTo2CharString( day-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gYearMonth( concat(</code>
                                        <code nobreak="false"> '--', </code>
                                        <emph>SMO</emph>
                                        <code nobreak="false">, '-', </code>
                                        <emph>SDA</emph>, <emph>STZ</emph>
                                        <code nobreak="false">) )</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                        or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>.</p></item></ulist></item><item><p>When a value of any primitive type is cast as <code nobreak="false">xs:gDay</code>,
                                the <code nobreak="false">xs:gDay</code> value <var>TV</var> is derived from
                                <var>ST</var> and <var>SV</var> as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:gDay</code>, then
                                        <var>TV</var> is <var>SV</var>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:dateTime</code>, then let
                                        <emph>SDA</emph> be <code nobreak="false">eg:convertTo2CharString( day-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gDay(
                                            concat( '---'</code>, <emph>SDA</emph>, <emph>STZ</emph>
                                        <code nobreak="false">))</code>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:date</code>, then let
                                        <emph>SDA</emph> be <code nobreak="false">eg:convertTo2CharString( day-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gDay(
                                            concat( '---'</code>, <emph>SDA</emph>, <emph>STZ</emph>
                                        <code nobreak="false">))</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                        or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>. </p></item></ulist></item><item><p>When a value of any primitive type is cast as <code nobreak="false">xs:gMonth</code>,
                                the <code nobreak="false">xs:gMonth</code> value <var>TV</var> is derived from
                                <var>ST</var> and <var>SV</var> as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:gMonth</code>, then
                                        <var>TV</var> is <var>SV</var>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:dateTime</code>, then let
                                        <emph>SMO</emph> be <code nobreak="false">eg:convertTo2CharString( month-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-dateTime(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gMonth(
                                            concat( '--' </code>, <emph>SMO</emph>, <emph>STZ</emph>
                                        <code nobreak="false">))</code>. </p></item><item><p>If <var>ST</var> is <code nobreak="false">xs:date</code>, then let
                                        <emph>SMO</emph> be <code nobreak="false">eg:convertTo2CharString( month-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code> and let <emph>STZ</emph> be
                                            <code nobreak="false">eg:convertTZtoString( timezone-from-date(</code>
                                        <var>SV</var>
                                        <code nobreak="false">))</code>; <var>TV</var> is <code nobreak="false">xs:gMonth(
                                            concat( '--'</code>, <emph>SMO</emph>, <emph>STZ</emph>
                                        <code nobreak="false">))</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                        or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>.</p></item></ulist></item></olist></div3><div3 id="casting-boolean"><head>Casting to <code nobreak="false">xs:boolean</code></head><p>When the target type <var>TT</var> is <code nobreak="false">xs:boolean</code>, the
                        resulting <code nobreak="false">xs:boolean</code> value <var>TV</var> is derived from
                        the source value <var>SV</var> as follows:</p><ulist><item><p>If <var>SV</var> is an instance of <code nobreak="false">xs:boolean</code>, then <var>TV</var>
                                is <var>SV</var>.</p></item><item><p>If <var>SV</var> is an instance of <code nobreak="false">xs:numeric</code> and
                                <var>SV</var> is <code nobreak="false">0</code>, <code nobreak="false">+0</code>, <code nobreak="false">-0</code>,
                                <code nobreak="false">0.0</code>, <code nobreak="false">0.0E0</code> or <code nobreak="false">NaN</code>, then
                                <var>TV</var> is <code nobreak="false">false</code>. </p></item><item><p>If <var>ST</var> is is an instance of <code nobreak="false">xs:numeric</code> and
                                <var>SV</var> is not one of the above values, then <var>TV</var>
                                is <code nobreak="false">true</code>. </p></item><item><p> If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code>
                                or <code nobreak="false">xs:string</code>, see 
                                    <specref ref="casting-from-strings"/>. </p></item></ulist></div3><div3 id="casting-to-binary"><head>Casting to <code nobreak="false">xs:base64Binary</code> and <code nobreak="false">xs:hexBinary</code></head><p>Values of type <code nobreak="false">xs:base64Binary</code> can be cast as
                        <code nobreak="false">xs:hexBinary</code> and vice versa, since the two types have the same
                        value space. Casting to <code nobreak="false">xs:base64Binary</code> and
                        <code nobreak="false">xs:hexBinary</code> is also supported from the same type and from
                        <code nobreak="false">xs:untypedAtomic</code>, <code nobreak="false">xs:string</code> and subtypes of
                        <code nobreak="false">xs:string</code> using <bibref ref="xmlschema-2"/> semantics.</p></div3><div3 id="casting-to-anyuri"><head>Casting to xs:anyURI</head><p>Casting to <code nobreak="false">xs:anyURI</code> is supported only from the same type,
                        <code nobreak="false">xs:untypedAtomic</code> or <code nobreak="false">xs:string</code>.</p><p>When a value of any <termref def="dt-primitive-type">primitive type</termref> is cast as <code nobreak="false">xs:anyURI</code>, the
                        <code nobreak="false">xs:anyURI</code> value <var>TV</var> is derived from the
                        <var>ST</var> and <var>SV</var> as follows:</p><ulist><item><p>If <var>ST</var> is <code nobreak="false">xs:untypedAtomic</code> or <code nobreak="false">xs:string</code> see 
                                    <specref ref="casting-from-strings"/>.
                             </p></item></ulist></div3><div3 id="casting-to-qname-and-notation"><head>Casting to xs:QName and xs:NOTATION</head><p>Casting from <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code> to
                  <code nobreak="false">xs:QName</code> or <code nobreak="false">xs:NOTATION</code> is described in 
                  <specref ref="casting-from-strings"/>.</p><p>It is also possible to cast from <code nobreak="false">xs:NOTATION</code> to <code nobreak="false">xs:QName</code>, 
                  or from <code nobreak="false">xs:QName</code> to
                  any type derived by restriction from <code nobreak="false">xs:NOTATION</code>. (Casting to <code nobreak="false">xs:NOTATION</code>
                  itself is not allowed, because <code nobreak="false">xs:NOTATION</code> is an abstract type.) The resulting
                  <code nobreak="false">xs:QName</code> or <code nobreak="false">xs:NOTATION</code> has the same prefix, local name, and namespace URI
                  parts as the supplied value.</p><note><p>See <specref ref="constructor-qname-notation"/> for a discussion of how the combination of
               atomization and casting might not produce the desired effect.</p></note></div3><div3 id="casting-to-ENTITY"><head>Casting to xs:ENTITY</head><p>
                  <bibref ref="xmlschema-2"/> says that <quote>The
                     value space of ENTITY is the set of all strings that match the 
                     NCName production ... and have been
                     declared as an unparsed entity in a document type definition.</quote>
                  However,
                  <bibref ref="xslt-40"/> and <bibref ref="xquery-40"/> do not check that constructed values of type <code nobreak="false">xs:ENTITY</code> match declared unparsed entities.  Thus, this rule is relaxed in this specification and, in casting to <code nobreak="false">xs:ENTITY</code> and types derived from it, no check is made that the values correspond to declared unparsed entities.
               </p></div3></div2><div2 id="casting-from-strings"><head>Casting from xs:string and xs:untypedAtomic</head><changes><change issue="1089" PR="1090" date="2024-03-19">
                  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. 
               </change><change issue="2520">
                  Casting from a string is now defined to follow the rules of XSD 1.1 in all cases, even if the processor
                  uses XSD 1.0 rules for validation of XML documents. In edge cases this means that casting from string
                  might succeed when validation fails.
               </change></changes><p>This section applies when the supplied value <var>SV</var>
               is an instance of <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>,
               including types derived from these by restriction. If the value is
               <code nobreak="false">xs:untypedAtomic</code>, it is treated in exactly the same way as a
               string containing the same sequence of characters.</p><p>The supplied string is mapped to a typed value of the target type as defined in <bibref ref="xmlschema11-2"/>. 
               Whitespace normalization is applied as indicated by the
               <code nobreak="false">whiteSpace</code> facet for the datatype. The resulting whitespace-normalized string 
               must be a valid lexical form for the datatype.  The semantics of casting follow the rules of
               XSD 1.1 validation (even for processors where validation would follow XSD 1.0 rules).  
               For example, <code nobreak="false">"13" cast as xs:unsignedInt</code> returns 
               the <code nobreak="false">xs:unsignedInt</code> typed 
               value <code nobreak="false">13</code>. This could also be written <code nobreak="false">xs:unsignedInt("13")</code>.</p><note><p>In the 4.0 version of this specification, casting from <code nobreak="false">xs:string</code>
            is defined to follow XSD 1.1. This means that some lexical forms not permitted by
            XSD 1.0 must be accepted: for example dates with the year zero, and <code nobreak="false">+INF</code>
            as a representation of positive infinity. Casting to <code nobreak="false">xs:anyURI</code> will
            never fail, because XSD 1.1 allows any sequence of characters in an <code nobreak="false">xs:anyURI</code>
            value.</p></note><p>The target type can be any simple type other than an
               abstract type. Specifically, it can be a type whose variety is atomic, union, or list.
               In each case the effect of casting to the target type is the same as constructing an element
               with the supplied value as its content, validating the element using the target type as
               the governing type, and atomizing the element to obtain its typed value.</p><p>When the target type is a derived type that is restricted by a pattern facet, the
               lexical form is first checked against the pattern before further casting
               is attempted (See <specref ref="casting-to-derived-types"/>).  If the lexical form does
               not conform to the pattern, a dynamic 
               error <errorref class="RG" code="0001" type="dynamic"/> is raised.</p><p>For example, consider a user-defined type <code nobreak="false">my:boolean</code> which is derived by
               restriction from <code nobreak="false">xs:boolean</code> and specifies the pattern facet <code nobreak="false">value="0|1"</code>.
               The expression <code nobreak="false">"true" cast as my:boolean</code> would fail with a dynamic
               error <errorref class="RG" code="0001" type="dynamic"/>.</p><p>Facets other than <code nobreak="false">pattern</code> are checked <emph>after</emph> the conversion.
               For example if there is a user-defined datatype called <code nobreak="false">my:height</code> 
               defined as a restriction of <code nobreak="false">xs:integer</code> with the facet <code nobreak="false">&lt;maxInclusive value="84"/&gt;</code>,
               then the expression <code nobreak="false">"100" cast as my:height</code> would fail with a dynamic
               error <errorref class="RG" code="0001" type="dynamic"/>.</p><p>Casting to the types <code nobreak="false">xs:NOTATION</code>, <code nobreak="false">xs:anySimpleType</code>, 
               or <code nobreak="false">xs:anyAtomicType</code> is not permitted because these types are abstract (they have
               no immediate instances).</p><p>Special rules apply when casting to namespace-sensitive types. The types <code nobreak="false">xs:QName</code>
               and <code nobreak="false">xs:NOTATION</code> are namespace-sensitive. Any type derived by restriction from 
               a namespace-sensitive type is itself namespace-sensitive, as is any union type having a
               namespace-sensitive type among its members, and any list type having a namespace-sensitive type
               as its item type. For details, see <specref ref="constructor-qname-notation"/>.</p><note><p>Since version 3.0 of this specification, casting has been allowed between <code nobreak="false">xs:QName</code>
               and <code nobreak="false">xs:NOTATION</code> in either direction; this was not permitted in previous Recommendations. Version 3.0 also removed
               the rule that only a string literal (rather than a dynamic string) may be cast to an <code nobreak="false">xs:QName</code></p></note><p>When casting to a numeric type:</p><ulist><item><p>If the value is too large or too small to be accurately represented by the implementation, 
                  it is handled as an overflow or underflow as defined in <specref ref="op.numeric"/>.</p></item><item><p>If the target type is <code nobreak="false">xs:float</code> or <code nobreak="false">xs:double</code>, the string <code nobreak="false">-0</code> (and equivalents
                  such as <code nobreak="false">-0.0</code> or <code nobreak="false">-000</code>) <rfc2119>should</rfc2119> be converted to the value negative zero.
                  However, if the implementation is reliant on an implementation of XML Schema 1.0 in which negative zero
                  is not part of the value space for these types, these lexical forms <rfc2119>may</rfc2119> be converted to positive zero.</p></item></ulist><p>
               In casting to <code nobreak="false">xs:decimal</code> or to a type derived from <code nobreak="false">xs:decimal</code>, 
               if the value is not too large or too small but nevertheless cannot be represented accurately 
               with the number of decimal digits available to the implementation, the implementation may round 
               to the nearest representable value or may raise a dynamic error <errorref class="CA" code="0006" type="dynamic"/>. 
               The choice of rounding algorithm and the choice between rounding and error behavior is 
               <termref def="implementation-defined"/>.
            </p><p>When casting to <code nobreak="false">xs:duration</code>, <code nobreak="false">xs:dateTime</code>, or <code nobreak="false">xs:time</code>,
            if the seconds component has more fractional digits than are supported by the implementation,
            excess digits <rfc2119>must</rfc2119> be truncated. This rule ensures that components
            other than the seconds component are unaffected: for example <code nobreak="false">xs:dateTime('2023-12-31T23:59:59.999999999')</code>
            is guaranteed to deliver an <code nobreak="false">xs:dateTime</code> value whose year component is 2023 rather than 2024.</p><note><p>Implementations are required to support millisecond precision or greater.</p></note><p>In casting to <code nobreak="false">xs:date</code>, <code nobreak="false">xs:dateTime</code>, <code nobreak="false">xs:gYear</code>, 
               or <code nobreak="false">xs:gYearMonth</code> 
               (or types derived from these), if the value is too large or too 
               small to be represented by the implementation, a dynamic error 
               <errorref class="DT" code="0001" type="dynamic"/> is raised.</p><p>In casting to a duration value, if the value is too large or too small to be represented by the 
               implementation, a dynamic error <errorref class="DT" code="0002" type="dynamic"/> is raised.</p><p>If the cast fails for any other reason, a dynamic error
               <errorref class="RG" code="0001" type="dynamic"/> is raised.</p></div2><div2 id="casting-non-primitive-types"><head>Casting involving non-primitive types</head><p>Casting from <code nobreak="false">xs:string</code> and <code nobreak="false">xs:untypedAtomic</code> to any other type
            (primitive or non-primitive) has been described in <specref ref="casting-from-strings"/>.
            This section defines how other casts to non-primitive types operate, including casting
            to types derived by restriction, to union types, and to list types.</p><div3 id="casting-to-derived-types"><head>Casting to derived types</head><p>Casting a value to a derived type can be separated into a number of cases. In these rules:</p><ulist><item><p>The types <code nobreak="false">xs:integer</code>, <code nobreak="false">xs:yearMonthDuration</code>,
               and <code nobreak="false">xs:dayTimeDuration</code> are treated as quasi-primitive types 
                  (alongside the 20 truly <termref def="dt-primitive-type">primitive types</termref>).</p></item><item><p>For any atomic type <var>T</var>, let <var>P(T)</var> denote the most specific primitive or quasi-primitive type
               such that <code nobreak="false">itemType-subtype(T, P(T))</code> is <code nobreak="false">true</code>.</p></item></ulist><p>The rules are then:</p><olist><item><p>When the source type <var>ST</var> is the same type as the target type <var>TT</var>: 
                     this case always succeeds, returning the source value <var>SV</var> unchanged.</p></item><item><p>When <code nobreak="false">itemType-subtype(ST, TT)</code> is <code nobreak="false">true</code>: 
                     see <specref ref="casting-from-derived-to-parent"/>. </p></item><item><p>When <var>TT</var> is the quasi-primitive type <code nobreak="false">xs:integer</code> 
                     and <code nobreak="false">SV</code> is an instance of <code nobreak="false">xs:numeric</code>:
                  see <specref ref="casting-to-integer"/>.</p></item><item><p>When <var>TT</var> is the quasi-primitive type <code nobreak="false">xs:yearMonthDuration</code> 
                     or <code nobreak="false">xs:dayTimeDuration</code> and <code nobreak="false">SV</code> is an instance of <code nobreak="false">xs:duration</code>:
                  see <specref ref="casting-to-duration-subtypes"/>.</p></item><item><p>When <var>P(ST)</var> is the same type as <var>P(TT)</var>: 
                     see <specref ref="casting-within-branch"/>.</p></item><item><p>Otherwise (<var>P(ST)</var> is not the same type as <var>P(TT)</var>): 
                     see <specref ref="casting-across-hierarchy"/>.</p></item></olist></div3><div3 id="casting-to-integer"><head>Casting to xs:integer</head><p>When an atomic item <code nobreak="false">SV</code> is cast as <code nobreak="false">xs:integer</code>, the
                            resulting <code nobreak="false">xs:integer</code> value <var>TV</var> is obtained as follows:</p><ulist><item><p>If <var>ST</var> is
                                    <code nobreak="false">xs:decimal</code>, <code nobreak="false">xs:float</code> or
                                    <code nobreak="false">xs:double</code>, then <var>TV</var> is <var>SV</var>
                                    with the fractional part discarded and the value converted to
                                    <code nobreak="false">xs:integer</code>. Thus, casting <code nobreak="false">3.1456</code>
                                    returns <code nobreak="false">3</code> while <code nobreak="false">-17.89</code> returns
                                    <code nobreak="false">-17</code>. Casting <code nobreak="false">3.124E1</code>
                                    returns <code nobreak="false">31</code>. If <var>SV</var> is too large to be
                                    accommodated as an integer, (see <bibref ref="xmlschema-2"/> for
                           <termref def="implementation-defined"/> limits on numeric values) a 
                           dynamic error is
                                    raised <errorref class="CA" code="0003"/>. If <var>SV</var> is
                                    one of the special <code nobreak="false">xs:float</code> or
                                    <code nobreak="false">xs:double</code> values <code nobreak="false">NaN</code>,
                           <code nobreak="false">INF</code>, or <code nobreak="false">-INF</code>, a dynamic error is raised
                                        <errorref class="CA" code="0002"/>.</p></item><item><p>In all other cases, the general rules of <specref ref="casting-to-derived-types"/> apply.</p></item></ulist><note><p>When casting to a subtype of <code nobreak="false">xs:integer</code> (for example, <code nobreak="false">xs:long</code>), the 
            rules in <specref ref="casting-to-derived-types"/> apply. Note, however, that these rules
            treat <code nobreak="false">xs:integer</code> as a quasi-primitive type.</p></note></div3><div3 id="casting-to-duration-subtypes"><head>Casting to <code nobreak="false">xs:yearMonthDuration</code> and <code nobreak="false">xs:dayTimeDuration</code></head><p>When the source value <var>SV</var> is an instance of <code nobreak="false">xs:duration</code> (including
               any subtype of <code nobreak="false">xs:duration</code>), then:</p><ulist><item><p>If the target type <var>TT</var> is <code nobreak="false">xs:yearMonthDuration</code>, the result
                  is an instance of <code nobreak="false">xs:yearMonthDuration</code> whose <code nobreak="false">months</code> component
                  is equal to the <code nobreak="false">months</code> component of <var>SV</var>. The <code nobreak="false">seconds</code>
                  component of <var>SV</var> is ignored.</p></item><item><p>If the target type <var>TT</var> is <code nobreak="false">xs:dayTimeDuration</code>, the result
                  is an instance of <code nobreak="false">xs:dayTimeDuration</code> whose <code nobreak="false">seconds</code> component
                  is equal to the <code nobreak="false">seconds</code> component of <var>SV</var>. The <code nobreak="false">months</code>
                  component of <var>SV</var> is ignored.</p></item></ulist><p>In all other cases, the general rules of <specref ref="casting-to-derived-types"/> apply.</p><note><p>In general, casting to <code nobreak="false">xs:yearMonthDuration</code> or <code nobreak="false">xs:dayTimeDuration</code>
                  loses information.</p></note><note><p>When casting to a subtype of <code nobreak="false">xs:dayTimeDuration</code> or 
                  <code nobreak="false">xs:yearMonthDuration</code>, the 
            rules in <specref ref="casting-to-derived-types"/> apply. Note, however, that these rules
            treat <code nobreak="false">xs:dayTimeDuration</code> and <code nobreak="false">xs:yearMonthDuration</code> as quasi-primitive types.</p></note></div3><div3 id="casting-from-derived-to-parent"><head>Casting from derived types to parent types</head><p>
               It is always possible to cast an atomic item <var>A</var> to a type <var>T</var>
               if the relation <code nobreak="false">A instance of T</code> is true, provided that <var>T</var>
               is not an abstract type.
            </p><p>For example, it is
              possible to cast an <code nobreak="false">xs:unsignedShort</code> to an
              <code nobreak="false">xs:unsignedInt</code>, to an <code nobreak="false">xs:integer</code>, to an
              <code nobreak="false">xs:decimal</code>, or to a union type
              whose member types are <code nobreak="false">xs:integer</code> and <code nobreak="false">xs:double</code>.</p><p>Since the value space of the original type is a subset
              of the value space of the target type, such a cast is always successful.</p><p>For the expression <code nobreak="false">A instance of T</code> to be true, <var>T</var> must be
               either an atomic type, or a union type that has no constraining facets. It cannot
               be a list type, nor a union type derived by restriction from another union type, nor
               a union type that has a list type among its member types.</p><p>The
            result will have the same value as the original, but will have a new type annotation:</p><ulist><item><p>If <var>T</var> is an atomic type, then the type annotation of the result is <code nobreak="false">T</code>.
               </p></item><item><p>If <var>T</var> is a union type, then the type of the result is an atomic type <code nobreak="false">M</code>
                  such that <var>M</var> is one of the atomic types in the transitive membership of
                  the union type <var>T</var> and <code nobreak="false">A instance of M</code> is true; if there is more
                  than one type <var>M</var> that satisfies these conditions (which could happen, for example,
                  if <var>T</var> is the union of two overlapping types such as <code nobreak="false">xs:int</code>
                  and <code nobreak="false">xs:positiveInteger</code>) then the first one is used, taking the member types
                  in the order in which they appear within the definition of the union type.</p></item></ulist></div3><div3 id="casting-within-branch"><head>Casting within a branch of the type hierarchy</head><p>It is possible to cast an <var>SV</var> to a <var>TT</var> if the type of the
                    <var>SV</var> and the <var>TT</var> type are both derived by restriction
               (directly or indirectly) from the same <termref def="dt-primitive-type">primitive type</termref>, provided that the
                    supplied value conforms to the constraints implied by the facets of the target
                    type.  This includes the case where the target type is derived from the type of the supplied value,
                    as well as the case where the type of the supplied value is derived from the target type.  For example, an instance of <code nobreak="false">xs:byte</code> can be cast as
                    <code nobreak="false">xs:unsignedShort</code>, provided the value is not negative.  </p><p>If the value does not conform to the facets defined for the target type, then a dynamic
                    error is raised <errorref class="RG" code="0001"/>. See <bibref ref="xmlschema-2"/>.
                    In the case of the pattern facet (which applies to the lexical space rather than
                    the value space), the pattern is tested against the canonical 
                    representation of the value, as defined for the source type (or the result
                    of casting the value to an <code nobreak="false">xs:string</code>, in the case of types that have no canonical
                     representation defined for them).</p><p>Note that this will cause casts to fail if the pattern excludes the canonical
                    lexical representation of the source type. For example, if the type
                    <code nobreak="false">my:distance</code> is defined as a restriction of <code nobreak="false">xs:decimal</code>
                    with a pattern that requires two digits after the decimal point, casting of an
                    <code nobreak="false">xs:integer</code> to <code nobreak="false">my:distance</code> will always fail, because
                    the canonical representation of an <code nobreak="false">xs:integer</code> does not conform to
                    this pattern.</p><p>In some cases, casting from a parent type to a derived type requires special
                    rules. See <specref ref="casting-to-durations"/> for rules regarding casting to
                    <code nobreak="false">xs:yearMonthDuration</code> and <code nobreak="false">xs:dayTimeDuration</code>.  See <specref ref="casting-to-ENTITY"/>, below, for casting to <code nobreak="false">xs:ENTITY</code> and types derived from it.</p></div3><div3 id="casting-across-hierarchy"><head>Casting across the type hierarchy</head><p>When the <var>ST</var> and the <var>TT</var> are derived, directly or
               indirectly, from different <termref def="dt-primitive-type">primitive types</termref>, this is called casting across the
                    type hierarchy. Casting across the type hierarchy is logically equivalent to
                    three separate steps performed in order. Errors can occur in either of the
                    latter two steps.</p><olist><item><p>Cast the <var>SV</var>, up the hierarchy, to the <termref def="dt-primitive-type">primitive type</termref> of the
                            source, as described in <specref ref="casting-from-derived-to-parent"/>.</p><olist><item><p>
If <var>SV</var> is an instance of <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>, check its value against the 
                           pattern facet of <var>TT</var>, and raise a dynamic error <errorref class="RG" code="0001"/> if the check fails.</p></item></olist></item><item><p>Let <var>P(TT)</var> be the most specific primitive or quasi-primitive type of which <var>TT</var>
                  is a subtype, as described in <specref ref="casting-to-derived-types"/>.</p><p>Cast the value to <var>P(TT)</var>, as described in
                                <specref ref="casting-from-primitive-to-primitive"/> if <var>P(TT)</var>
                     is primitive, or as described in <specref ref="casting-to-derived-types"/> if <var>P(TT)</var>
                     is quasi-primitive.</p><p>If <var>TT</var> is derived from <code nobreak="false">xs:NOTATION</code>, assume for the
                        purposes of this rule that casting to <code nobreak="false">xs:NOTATION</code> succeeds.</p></item><item><p>Cast the value down to the target type <var>TT</var>, as described in <specref ref="casting-within-branch"/>
                        </p></item></olist></div3><div3 id="casting-to-union"><head>Casting to union types</head><p>If the target type of a cast expression (or a constructor function) is a type with variety union, the
               supplied value must be one of the following:</p><olist><item><p>A value of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>.
               This case follows the general rules for casting from strings, and has already been
               described in <specref ref="casting-from-strings"/>.</p><p>If the union type has a pattern facet, the pattern is tested against the supplied
                     value after whitespace normalization, using the <code nobreak="false">whiteSpace</code>
                     normalization rules of the member datatype against which validation succeeds.</p></item><item><p>A value that is an instance of one of the atomic types in the transitive
               membership of the union type, and of the union type itself. This case has already been described in
               <specref ref="casting-from-derived-to-parent"/></p><p>This situation only applies when the value is an instance of the union type,
                  which means it will never apply when the union is derived by facet-based restriction
                  from another union type.</p></item><item><p>A value that is castable to one or more of the atomic types in the transitive membership
                  of the union type (in the sense that the <code nobreak="false">castable as</code> operator returns <code nobreak="false">true</code>).</p><p>In this case the supplied value is cast to each atomic type in the transitive membership
                     of the union type in turn (in the order in which the member types appear in the declaration)
                     until one of these casts is successful; if none of them is successful, a dynamic error occurs
                     <errorref class="RG" code="0001"/>. If the union type has constraining facets then the
                     resulting value must satisfy these facets, otherwise a dynamic error occurs 
                     <errorref class="RG" code="0001"/>.</p><p>If the union type has a pattern facet, the pattern is tested against the canonical
                  representation of the result value.</p><p>Only the atomic types in the transitive membership of the union type are considered. The
                  union type may have list types in its transitive membership, but (unless the supplied value
                  is of type <code nobreak="false">xs:string</code> or <code nobreak="false">xs:untypedAtomic</code>, in which case the
                  rules in <specref ref="casting-from-strings"/> apply), any list types in the membership
                  are effectively ignored.</p></item></olist><p>If more than one of these conditions applies, then the casting is done according to the rules
            for the first condition that applies.</p><p>If none of these conditions applies, the cast fails with a dynamic error
            <errorref class="RG" code="0001"/>.</p><p>Example: consider a type <var>U</var> whose member types are <code nobreak="false">xs:integer</code>
               and <code nobreak="false">xs:date</code>.</p><ulist><item><p>The expression <code nobreak="false">"123" cast as U</code> returns the
                  <code nobreak="false">xs:integer</code> value <code nobreak="false">123</code>.</p></item><item><p>The expression <code nobreak="false">current-date() cast as U</code> returns
                     the current date as an instance of <code nobreak="false">xs:date</code>.</p></item><item><p>The expression <code nobreak="false">23.1 cast as U</code> returns the <code nobreak="false">xs:integer</code>
                  value <code nobreak="false">23</code>.</p></item></ulist><p>Example: consider a type <var>V</var> whose member types are <code nobreak="false">xs:short</code>
               and <code nobreak="false">xs:negativeInteger</code>.</p><ulist><item><p>The expression <code nobreak="false">"-123" cast as V</code> returns the
                  <code nobreak="false">xs:short</code> value <code nobreak="false">-123</code>.</p></item><item><p>The expression <code nobreak="false">"-100000" cast as V</code> returns the
                  <code nobreak="false">xs:negativeInteger</code> value <code nobreak="false">-100000</code>.</p></item><item><p>The expression <code nobreak="false">93.7 cast as V</code> returns the
                  <code nobreak="false">xs:short</code> value <code nobreak="false">93</code>.</p></item><item><p>The expression <code nobreak="false">"93.7" cast as V</code> raises
                  a dynamic error <errorref class="RG" code="0001"/> on the grounds that the string
               <code nobreak="false">"93.7"</code> is not in the lexical space of the union type.</p></item></ulist><p>Example: consider a type <var>W</var> that is derived from the above type <var>V</var>
               by restriction, with a pattern facet of <code nobreak="false">-?\d\d</code>.</p><ulist><item><p>The expression <code nobreak="false">"12" cast as V</code> returns the
                     <code nobreak="false">xs:short</code> value <code nobreak="false">12</code>.</p></item><item><p>The expression <code nobreak="false">"123" cast as V</code> raises
                     an dynamic error <errorref class="RG" code="0001"/> on the grounds that the string
                     <code nobreak="false">"123"</code> does not match the pattern facet.</p></item></ulist></div3><div3 id="casting-to-list"><head>Casting to list types</head><p>If the target type of a cast expression (or a constructor function) is a
            type with variety <code nobreak="false">list</code>, the supplied value must be of type <code nobreak="false">xs:string</code> or
            <code nobreak="false">xs:untypedAtomic</code>. The rules follow the general principle for
            all casts from <code nobreak="false">xs:string</code> outlined in <specref ref="casting-from-strings"/>.</p><p diff="add" at="issue687">If the supplied value is not of type <code nobreak="false">xs:string</code> or
               <code nobreak="false">xs:untypedAtomic</code>, a type error is raised 
               <xerrorref spec="XP" class="TY" code="0004" type="type"/>.</p><p>The semantics of the operation are consistent with validation: that is,
            the effect of casting a string <var>S</var> to a list type <var>L</var> is the same as
            constructing an element or attribute node whose string value is <var>S</var>,
            validating it using <var>L</var> as the governing type, and atomizing the resulting
            node. The result will always be either failure, or a sequence of zero or
            more atomic items each of which is an instance of the item type of <var>L</var>
            (or if the item type of <var>L</var> is a union type, an instance of one of the
            atomic types in its transitive membership).</p><p>If the item type of the list type is namespace-sensitive, then the 
               namespace bindings in the static context will be used to
            resolve any namespace prefix, in the same way as when the target type is
            <code nobreak="false">xs:QName</code>.</p><p>If the list type has a <code nobreak="false">pattern</code> facet, the pattern must match
            the supplied value after collapsing whitespace (an operation equivalent to the
            use of the <function>fn:normalize-space</function> function).</p><p>For example, the expression <code nobreak="false">cast "A B C D" as xs:NMTOKENS</code>
            produces a sequence of four <code nobreak="false">xs:NMTOKEN</code> values, 
            <code nobreak="false">("A", "B", "C", "D")</code>.</p><p>For example, given a user-defined type <code nobreak="false">my:coordinates</code> defined
            as a list of <code nobreak="false">xs:integer</code> with the facet <code nobreak="false">&lt;xs:length value="2"/&gt;</code>,
            the expression <code nobreak="false">my:coordinates("2 -1")</code> will return a sequence of two
            xs:integer values <code nobreak="false">(2, -1)</code>, while the expression <code nobreak="false">my:coordinates("1 2 3")</code>
            will result in a dynamic error because the length of the list does not conform to the
            <code nobreak="false">length</code> facet. The expression <code nobreak="false">my:coordinates("1.0 3.0")</code>
            will also fail because the strings <code nobreak="false">1.0</code> and <code nobreak="false">3.0</code> 
               are not in the lexical space of <code nobreak="false">xs:integer</code>.</p></div3></div2></div1></body><back><div1 id="biblio"><head>References</head><div2 id="normative-biblio"><head>Normative references</head><blist><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="charmod" key="Character Model for the World Wide Web 1.0: Fundamentals" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                  <titleref href="https://www.w3.org/TR/charmod/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">Character Model for the World Wide Web 1.0:
                     Fundamentals</titleref>,
                  Martin J. Dürst, François Yergeau, <emph>et. al.</emph>, Editors.
                  World Wide Web Consortium,
                  15 February 2015.
                  This version is http://www.w3.org/TR/2005/REC-charmod-20050215/.
                  The <loc href="https://www.w3.org/TR/charmod/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">latest version</loc>
                  is available at https://www.w3.org/TR/charmod/.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="html5" key="HTML: Living Standard" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                  <titleref href="https://html.spec.whatwg.org/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">HTML: Living Standard</titleref>.
                  WHATWG,
                  18 November 2022.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="dom-ls" key="DOM: Living Standard" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                  <titleref href="https://dom.spec.whatwg.org/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">DOM: Living Standard</titleref>.
                  WHATWG,
                  26 October 2022.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="olson" key="IANA Timezone Database" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                  The <emph>tz</emph> timezone database, available at 
                  <loc href="http://www.iana.org/time-zones" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.iana.org/time-zones</loc>.
                  It is <termref def="implementation-defined"/> which version of the database is used.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ieee754-2019" key="IEEE 754-2019" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IEEE. <emph>IEEE Standard for
                  Floating-Point Arithmetic.</emph>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ieee1003.1-2024" key="IEEE 1003.1-2024" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                  <titleref href="https://pubs.opengroup.org/onlinepubs/9799919799/functions/time.html" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">Open Group Base Specifications Issue 8</titleref>. IEEE, 2024.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ieee802-3" key="IEEE 802-3" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">“IEEE Standard for Ethernet,” in IEEE Std
               802.3-2022 (Revision of IEEE Std 802.3-2018). 29 July 2022.
               doi: 10.1109/IEEESTD.2022.9844436.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ISO3166" key="ISO 3166-1" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">ISO (International Organization for Standardization)
					<emph>Codes for the representation of names of countries
					 and their subdivisions - Part 1: Country codes</emph> ISO 3166-1:2013.
                    </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ISO8601" key="ISO 8601" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">ISO (International Organization for
                  Standardization). <emph>Representations of dates and times. Third edition,
                     2004-12-01.</emph> ISO 8601:2004(E). Available from:
                  <loc href="http://www.iso.org/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.iso.org/"</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ISO10967" key="ISO 10967" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">ISO (International Organization
for Standardization). <emph>ISO/IEC 10967-1:2012, Information
technology—Language Independent Arithmetic—Part 1:
Integer and floating point arithmetic</emph> [Geneva]: International
Organization for Standardization, 2012. Available from: <loc href="http://www.iso.org/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.iso.org/</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ISO15924" key="ISO 15924" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">ISO (International Organization for Standardization) 
                  <emph>Information and documentation — Codes
                     for the representation of names of scripts</emph> ISO 15924:2004, 
                  January 2004.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ISO15924_register" key="ISO 15924 Register" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Unicode Consortium. 
                  <emph>Codes for the representation of names of scripts — Alphabetical list of four-letter script codes.</emph>
                  See <loc href="http://www.unicode.org/iso15924/iso15924-codes.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.
                  Retrieved February 2013; continually updated.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="LEIRI" key="Legacy extended IRIs for XML resource identification" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"><emph>Legacy extended IRIs for XML resource identification</emph>.
                  Henry S. Thomson, Richard Tobin, and Norman Walsh (eds), World Wide Web Consortium. 3 November 2008. Available at
                  <loc href="http://www.w3.org/TR/leiri/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/leiri/</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc1321" key="RFC 1321" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 1321: The MD5 Message-Digest Algorithm. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc1321.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc1321.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc2376" key="RFC 2376" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 2376: XML Media Types. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc2376.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc2376.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc3986" key="RFC 3986" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 3986: Uniform
                  Resource Identifiers (URI): Generic Syntax. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc3986.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc3986.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc3987" key="RFC 3987" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 3987:
                  Internationalized Resource Identifiers (IRIs).</emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc3987.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc3987.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc4180" key="RFC 4180" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 4180:
                  Common Format and MIME Type for Comma-Separated Values (CSV) Files.</emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc4180.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc4180.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc6151" key="RFC 6151" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 6151:
                  Updated Security Considerations for
                  the MD5 Message-Digest and the HMAC-MD5 Algorithms</emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc6151.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc6151.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc7159" key="RFC 7159" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 7159: The Javascript Object Notation (JSON) Data Interchange Format</emph> Available at:
                  <loc href="http://www.rfc-editor.org/rfc/rfc7159.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.rfc-editor.org/rfc/rfc7159.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc7303" key="RFC 7303" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">H. Thompson and C. Lilley. <emph>XML Media Types</emph>.
                  IETF RFC 7303. See <loc href="http://www.ietf.org/rfc/rfc7303.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc7303.txt</loc>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="fips180-4" key="FIPS 180-4" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">National Institute of Standards and Technology.
                 <emph>Secure Hash Standard (SHS)</emph>. FIPS PUB 180-4. August 2015. 
                  See <loc href="http://dx.doi.org/10.6028/NIST.FIPS.180-4" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://dx.doi.org/10.6028/NIST.FIPS.180-4</loc>. </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="UNICODE-TR15" key="UAX #15" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"><emph>Unicode Standard Annex #15: Unicode Normalization
                     Forms</emph>. 
                  Ed. Mark Davis and Ken Whistler, Unicode Consortium.
                  The current version is 16.0.0, dated 2024-08-14.
                  As with <bibref ref="Unicode"/>, the version to be used is <termref def="implementation-defined"/>.
                  Available at:
                  <loc href="http://www.unicode.org/reports/tr15/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.unicode.org/reports/tr15/</loc>.                 
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="UNICODE-TR29" key="UAX #29" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"><emph>Unicode Standard Annex #29: Unicode Text Segmentation</emph>. 
                  Ed. Josh Hadley, Unicode Consortium.
                  The current version is 16.0.0, dated 2024-08-28.
                  As with <bibref ref="Unicode"/>, the version to be used is <termref def="implementation-defined"/>.
                  Available at:
                  <loc href="http://www.unicode.org/reports/tr29/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.unicode.org/reports/tr29/</loc>.                 
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="Unicode" key="The Unicode Standard" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
The Unicode Consortium, Reading, MA, Addison-Wesley, 2016. <emph>The Unicode Standard</emph>
as updated from time to time by the publication of new versions. See 
<loc href="http://www.unicode.org/standard/versions/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.unicode.org/standard/versions/</loc>
for the latest version and additional information on versions of the standard and of the Unicode Character Database. 
The version of Unicode to be used is <termref def="implementation-defined"/>,
but implementations are recommended to use the latest Unicode version;
currently, Version 9.0.0.
</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="UNICODE-TR10" key="UTS #10" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"><emph>Unicode
                  Technical Standard #10: Unicode Collation Algorithm</emph>. 
                  Ed. Mark Davis and Ken Whistler, Unicode Consortium. The current version is 16.0.0, dated 2024-08-22.
                  As with <bibref ref="Unicode"/>, the version to be used is <termref def="implementation-defined"/>. 
                  Available at: <loc href="http://www.unicode.org/reports/tr10/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="UNICODE-TR35" key="UTS #35" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"><emph>Unicode
                  Technical Standard #35: Unicode Locale Data Markup Language</emph>. 
                  Ed Mark Davis <emph>et al</emph>, Unicode Consortium. The current version is 47, dated 2025-03-11.
                  As with <bibref ref="Unicode"/>, the version to be used is <termref def="implementation-defined"/>.
                  Available at: <loc href="http://www.unicode.org/reports/tr35/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="XINFO" key="XML Infoset" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">World Wide Web
Consortium. <emph>XML Information Set (Second Edition).</emph> W3C Recommendation 4 February 2004. See
<loc href="http://www.w3.org/TR/xml-infoset/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/xml-infoset/</loc>
</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml" key="Extensible Markup Language (XML) 1.0 (Fifth Edition)" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml11" key="Extensible Markup Language (XML) 1.1 Recommendation" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xpath" key="XML Path Language (XPath) Version 1.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xpath-40" key="XPath 4.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                 <emph>CITATION: T.B.D.</emph>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="binary-40" key="EXPath Binary Module 4.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                 <emph>CITATION: T.B.D.</emph>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xslt10" key="XSL Transformations (XSLT) Version 1.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xslt20" key="XSL Transformations (XSLT) Version 2.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xslt-40" key="XSL Transformations (XSLT) Version 4.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                 <emph>CITATION: T.B.D.</emph>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xpath-datamodel-30" key="XQuery and XPath Data Model (XDM) 3.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xpath-datamodel-31" key="XQuery and XPath Data Model (XDM) 3.1" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xpath-datamodel-40" key="XQuery and XPath Data Model (XDM) 4.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xslt-xquery-serialization-31" key="XSLT and XQuery Serialization 3.1" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xquery-semantics" key="XQuery 1.0 and XPath 2.0 Formal Semantics" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xquery-40" key="XQuery 4.0: An XML Query Language" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                 <emph>CITATION: T.B.D.</emph>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xinclude" key="XML Inclusions (XInclude) Version 1.0 (Second Edition)" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlschema-1" key="XML Schema Part 1: Structures Second Edition" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> XML
                        Schema Part 1: Structures Second Edition, Oct 28 2004. Available at: 
						<loc href="http://www.w3.org/TR/xmlschema-1/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/xmlschema-1/</loc>
						</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlschema-2" key="XML Schema Part 2: Datatypes Second Edition" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"> XML Schema
                        Part 2: Datatypes Second Edition, Oct. 28 2004. Available at: 
						<loc href="http://www.w3.org/TR/xmlschema-2/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/xmlschema-2/</loc>
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlschema11-1" key="XSD 1.1 Part 1" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xmlschema11-2" key="XSD 1.1 Part 2" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="xml-names" key="Namespaces in XML" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"/><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="invisible-xml" key="Invisible XML" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                  <titleref href="https://invisiblexml.org/1.0/" xlink:type="simple" xlink:show="new" xlink:actuate="onRequest">Invisible XML Specification</titleref>,
                  Steven Pemberton, editor.
                  World Wide Web Consortium,
                  20 June 2020.
                  This version is https://invisiblexml.org/1.0/.
                  The <loc href="https://invisiblexml.org/current/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">latest version</loc>
                  is available at https://invisiblexml.org/current/.</bibl></blist></div2><div2 id="non-normative-biblio"><head>Non-normative references</head><blist><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="BLAKE3" key="BLAKE3 Hashing" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
				  <emph>Blake3 Algorithm Specification</emph>. Available at:
				  <loc href="https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf</loc>
			   </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="CALCALC" key="Calendrical Calculations" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Edward M. Reingold and Nachum Dershowitz.
<emph>Calendrical Calculations Millennium edition (2nd Edition)</emph>. Cambridge University Press, 
ISBN 0 521 77752 6.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="CLDR" key="Unicode CLDR" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">CLDR - Unicode Common Locale Data Repository. Available at:
                  <loc href="http://cldr.unicode.org" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://cldr.unicode.org</loc>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="charmod-normalization" key="Character Model for the World Wide Web 1.0: Normalization" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Character Model for the World Wide Web
                  1.0: Normalization, Last Call Working Draft. Available at:
                  <loc href="http://www.w3.org/TR/2004/WD-charmod-norm-20040225/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/2004/WD-charmod-norm-20040225/</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="expath" key="EXPath" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">EXPath: Collaboratively Defining Open Standards for Portable XPath Extensions.
               <loc href="http://expath.org/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://expath.org/</loc>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="exquery" key="EXQuery" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">EXQuery: Collaboratively Defining Open Standards for Portable XQuery Extensions.
                  <loc href="http://exquery.org/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://exquery.org/</loc>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="exslt" key="EXSLT" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">EXSLT: A Community Initiative to Provide Extensions to XSLT.
                  <loc href="https://exslt.github.io" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://exslt.github.io</loc>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="functx" key="FunctX" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">FunctX Functions. 
                  <loc href="http://www.functx.com/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.functx.com/</loc>.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="Goessner" key="Goessner" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">Stefan Goessner. Converting Between XML and JSON.
               <loc href="https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html</loc>.
               31 May 2006.</bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="HTML40" key="HTML 4.0" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">HTML 4.01 Recommendation, 24 December
1999. Available at:
<loc href="http://www.w3.org/TR/REC-html40/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/REC-html40/</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="ICU" key="ICU" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">ICU - International Components for Unicode. Available at <loc href="http://site.icu-project.org" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://site.icu-project.org</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="POSIX.1-2008" key="POSIX.1-2008" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">
                  <emph>The Open Group Base Specifications Issue 7 (IEEE Std 1003.1-2008)</emph>.
                  Available at: <loc href="http://pubs.opengroup.org/onlinepubs/9699919799/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://pubs.opengroup.org/onlinepubs/9699919799/</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc822" key="RFC 822" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 822: Standard for the Format of ARPA Internet Text Messages. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc822.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc822.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc850" key="RFC 850" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 850: Standard for Interchange of USENET Messages. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc850.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc850.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc1036" key="RFC 1036" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 1036: Standard for Interchange of USENET Messages. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc1036.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc1036.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc1123" key="RFC 1123" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 1123: Requirements for Internet Hosts -- Application and Support. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc1123.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc1123.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc2616" key="RFC 2616" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc2616.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc2616.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="rfc3339" key="RFC 3339" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">IETF. <emph>RFC 3339: Date and Time on the Internet: Timestamps. </emph> Available at:
                  <loc href="http://www.ietf.org/rfc/rfc3339.txt" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.ietf.org/rfc/rfc3339.txt</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="UNICODE-TR18" key="UTS #18" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest"><emph>Unicode
                  Technical Standard #18: Unicode Regular Expressions</emph>. 
                  Ed. Mark Davis and Andy Heniger, Unicode Consortium. The current version is 17, dated 2013-11-19. Available at:
                  <loc href="http://www.unicode.org/reports/tr18/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.unicode.org/reports/tr18/</loc>.
               </bibl><bibl xmlns:xlink="http://www.w3.org/1999/xlink" id="Working-With-Timezones" key="Working With Timezones" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">World Wide Web Consortium Working Group Note. 
					 <emph>Working With Timezones, October 13, 2005.</emph> Available at:
<loc href="http://www.w3.org/TR/2005/NOTE-timezone-20051013/" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">http://www.w3.org/TR/2005/NOTE-timezone-20051013/</loc>.
               </bibl></blist></div2></div1><div1 id="error-summary"><head>Error codes</head><p>The error text provided with these errors is non-normative.</p><error-list><error class="ER" code="0000" label="Unidentified error." type="dynamic"><p>Error code used by <function>fn:error</function> when no other error code is provided.</p></error><error class="AP" code="0001" label="Wrong number of arguments." type="dynamic"><p>Raised when <function>fn:apply</function> is called and the arity of the supplied function is not
                  the same as the number of members in the supplied array.</p></error><error class="AR" code="0001" label="Division by zero." type="dynamic"><p>This error is raised whenever an attempt is made to divide by zero.</p></error><error class="AR" code="0002" label="Numeric operation overflow/underflow." type="dynamic"><p>This error is raised whenever numeric operations result in an overflow or underflow.</p></error><error class="AY" code="0001" label="Array index out of bounds." type="dynamic"><p>This error is raised when an integer used to select a member of an array is outside the range of values for that array.</p></error><error class="AY" code="0002" label="Negative array length." type="dynamic"><p>This error is raised when the <code nobreak="false">$length</code> argument to <function>array:subarray</function> is negative.</p></error><error class="CA" code="0001" label="Input value too large for decimal." type="dynamic"><p>Raised when casting to <code nobreak="false">xs:decimal</code> if the supplied value exceeds the
               implementation-defined limits for the datatype.</p></error><error class="CA" code="0002" label="Invalid lexical value." type="dynamic"><p>Raised by <function>fn:resolve-QName</function> and <function>fn:QName</function> when a supplied value does not have the lexical
               form of a QName or URI respectively; and when casting to decimal, if the supplied value is <code nobreak="false">NaN</code> or Infinity.</p></error><error class="CA" code="0003" label="Input value too large for integer." type="dynamic"><p>Raised when casting to <code nobreak="false">xs:integer</code> if the supplied value exceeds the
                  implementation-defined limits for the datatype.</p></error><error class="CA" code="0005" label="NaN supplied as float/double value." type="dynamic"><p>Raised when multiplying or dividing a duration by a number, if the number supplied is <code nobreak="false">NaN</code>.</p></error><error class="CA" code="0006" label="String to be cast to decimal has too many digits of precision." type="dynamic"><p>Raised when casting a string to <code nobreak="false">xs:decimal</code> if the string has more digits of precision
               than the implementation can represent (the implementation also has the option of rounding).</p></error><error class="CH" code="0001" label="Codepoint not valid." type="dynamic"><p diff="chg" at="2023-06-12">Raised by <function>fn:codepoints-to-string</function> if the input contains an integer that is not the codepoint
               of a <termref def="dt-permitted-character">permitted character</termref>.</p></error><error class="CH" code="0002" label="Unsupported collation." type="dynamic"><p>Raised by any function that uses a collation if the requested collation is not recognized.</p></error><error class="CH" code="0003" label="Unsupported normalization form." type="static"><p>Raised by <function>fn:normalize-unicode</function> if the requested normalization form is not
               supported by the implementation.</p></error><error class="CH" code="0004" label="Collation does not support collation units." type="dynamic"><p>Raised by functions such as <function>fn:contains</function> if the requested collation does
               not operate on a character-by-character basis.</p></error><error class="CH" code="0005" label="Unrecognized or invalid character name." type="dynamic"><p diff="chg" at="2023-06-12">Raised by <function>fn:char</function> if the supplied character name is not recognized, or
               if it represents a codepoint that is not
               a <termref def="dt-permitted-character">permitted character</termref>.</p></error><error class="CV" code="0001" label="CSV field quoting error." type="dynamic"><p>Raised when parsing CSV input if a syntax error in the input CSV is found.</p></error><error class="CV" code="0002" label="Invalid CSV delimiter error." type="dynamic"><p>Raised when parsing CSV input if the <code nobreak="false">field-separator</code>,
                  <code nobreak="false">record-separator</code>, or <code nobreak="false">quote-character</code> option is set to
                  an invalid value.</p></error><error class="CV" code="0003" label="Duplicate CSV delimiter error." type="dynamic"><p>Raised when parsing CSV input if the same delimiter character is assigned
                  to more than one role.</p></error><error class="CV" code="0004" label="Argument supplied is not a known column name." type="dynamic"><p>Raised by the function from the <code nobreak="false">get</code> entry of
                  <code nobreak="false">csv-columns-record</code>, if its <code nobreak="false">$key</code> argument is an
                  <code nobreak="false">xs:string</code> and is not one of the known column names.</p></error><error class="DC" code="0001" label="No context document." type="dynamic"><p>Raised by <function>fn:id</function>, <function>fn:idref</function>, and <function>fn:element-with-id</function>
                  if the node that identifies the tree to be searched is a node in a tree whose root is not
                  a document node.</p></error><error class="DC" code="0002" label="Error retrieving resource." type="dynamic"><p>Raised by <function>fn:doc</function>, <function>fn:collection</function>, and <function>fn:uri-collection</function>
               to indicate that either the supplied URI cannot be dereferenced to obtain a resource, or the resource
               that is returned is not parseable as XML.</p></error><error class="DC" code="0003" label="Function not defined as deterministic." type="dynamic"><p>Raised by <function>fn:doc</function>, <function>fn:collection</function>, and <function>fn:uri-collection</function> 
                  to indicate that it is not possible to
               return a result that is guaranteed deterministic.</p></error><error class="DC" code="0004" label="Invalid collection URI." type="dynamic"><p>Raised by <function>fn:collection</function> and <function>fn:uri-collection</function> 
                  if the argument is not a valid <code nobreak="false">xs:anyURI</code>.</p></error><error class="DC" code="0005" label="Invalid URI reference." type="dynamic"><p>Raised (optionally) by <function>fn:doc</function> if the argument 
                  is not a valid <code nobreak="false">xs:anyURI</code>.</p></error><error class="DC" code="0006" label="String cannot be parsed as XML." type="dynamic"><p>Raised by <function>fn:parse-xml</function> and <function>fn:parse-xml-fragment</function>
                  if the supplied string is not well-formed and namespace-well-formed XML.</p></error><error class="DC" code="0007" label="String passed to fn:parse-xml is not a DTD-valid XML document." type="dynamic"><p>Raised by <function>fn:parse-xml</function> if DTD validation is requested and the supplied string 
                  has no DTD or is not valid against the DTD.</p></error><error class="DC" code="0008" label="Invalid value for the xsd-validation option of fn:parse-xml." type="dynamic"><p>Raised when the <code nobreak="false">xsd-validation</code> option to <function>fn:parse-xml</function> is supplied,
                  and the value is not one of the permitted values; for example if the option <code nobreak="false">type Q{U}NNN</code>
                  is used, and <code nobreak="false">Q{U}NNN</code> does not identify a type in the static context.</p></error><error class="DC" code="0009" label="Processor is not schema-aware." type="dynamic"><p>Raised when the <code nobreak="false">xsd-validation</code> option to <function>fn:parse-xml</function> is set to
                  a value other than <code nobreak="false">skip</code>, if the processor is not schema-aware.</p></error><error class="DC" code="0010" label="The processor does not support serialization." type="dynamic"><p>Raised when <function>fn:serialize</function> is called and the processor does not support serialization,
               in cases where the host language makes serialization an optional feature.</p></error><error class="DC" code="0011" label="String passed to fn:parse-html is not a well-formed HTML document." type="dynamic"><p>Raised by <function>fn:parse-html</function> if the supplied string is not a well-formed HTML document.</p></error><error class="DC" code="0013" label="No validating XML parser available." type="dynamic"><p>Raised when the <code nobreak="false">dtd-validation</code> option to <function>fn:parse-xml</function> is set,
                  if no validating XML parser is available. Note: it is <rfc2119>recommended</rfc2119>
               that all processors should support the <code nobreak="false">dtd-validation</code> option, but there
               may be environments (such as web browsers) where this is not practically feasible.</p></error><error class="DC" code="0014" label="String passed to fn:parse-xml is not a schema-valid XML document." type="dynamic"><p>Raised by <function>fn:parse-xml</function> if XSD validation is requested and the XML document
                  represented by the supplied string is not valid against the relevant XSD schema.</p></error><error class="DC" code="0015" label="Unable to compile schema for fn:xsd-validator." type="dynamic"><p>Raised by <function>fn:xsd-validator</function> if it is not possible to assemble a valid and
                  consistent schema.</p></error><error class="DF" code="1280" label="Invalid decimal format name." type="dynamic"><p>This error is raised if the decimal format name supplied to <function>fn:format-number</function> is not a valid QName,
			   or if the prefix in the QName is undeclared, or if there is no decimal format in the static context with
			   a matching name.</p></error><error class="DF" code="1290" label="Invalid decimal format property." type="dynamic"><p>This error is raised if a decimal format value supplied to
               <function>fn:format-number</function> is not valid for the associated property,
               or if the properties of the decimal format resulting from a supplied map
               do not have distinct values.</p></error><error class="DF" code="1310" label="Invalid decimal format picture string." type="dynamic"><p>This error is raised if the picture string supplied to <function>fn:format-number</function> or 
                  <function>fn:format-integer</function> has invalid syntax.</p></error><error class="DT" code="0001" label="Overflow/underflow in date/time operation." type="dynamic"><p>Raised when casting to date/time datatypes, or performing arithmetic with date/time values, if
               arithmetic overflow or underflow occurs.</p></error><error class="DT" code="0002" label="Overflow/underflow in duration operation." type="dynamic"><p>Raised when casting to duration datatypes, or performing arithmetic with duration values, if
                  arithmetic overflow or underflow occurs.</p></error><error class="DT" code="0003" label="Invalid timezone value." type="dynamic"><p>Raised by <code nobreak="false">adjust-date-to-timezone</code> and related functions if the supplied timezone is invalid.</p></error><error class="DT" code="0004" label="No timezone data available" type="dynamic"><p>Raised by <code nobreak="false">civil-timezone</code> if no timezone data is available for the given date/time and place.</p></error><error class="DT" code="0005" label="Invalid combination of date/time fields" type="dynamic"><p>Raised by <code nobreak="false">build-dateTime</code> if the set of fields supplied does not correspond to those present in one of the
                  <termref def="dt-gregorian"/> types.</p></error><error class="DT" code="0006" label="Invalid component of date/time vallue" type="dynamic"><p>Raised by <code nobreak="false">build-dateTime</code> if one of the fields supplied has a value that is outside the
                  supported range.</p></error><error class="FD" code="1340" label="Invalid date/time formatting parameters." type="dynamic"><p>This error is raised if the picture string or calendar supplied to <function>fn:format-date</function>, <function>fn:format-time</function>, 
			   or <function>fn:format-dateTime</function> has invalid syntax.</p></error><error class="FD" code="1350" label="Invalid date/time formatting component." type="dynamic"><p>This error is raised if the picture string supplied to <function>fn:format-date</function> 
			   selects a component that is not present in a date, or if the picture string supplied to <function>fn:format-time</function> 
			   selects a component that is not present in a time.</p></error><error class="HA" code="0001" label="Invalid algorithm." type="dynamic"><p>Raised by <function>fn:hash</function> if the effective value of the supplied
               algorithm is not one of the values supported by the implementation.</p></error><error class="JS" code="0001" label="JSON syntax error." type="dynamic"><p>Raised by functions such as <function>fn:json-doc</function>, <function>fn:parse-json</function> 
                  or <function>fn:json-to-xml</function> 
                  if the string supplied as input does not conform to the JSON grammar (optionally with implementation-defined extensions).</p></error><error class="JS" code="0003" label="JSON duplicate keys." type="dynamic"><p>Raised by functions such as <function>map:merge</function>, <function>fn:json-doc</function>, 
                  <function>fn:parse-json</function> or <function>fn:json-to-xml</function> 
                  if the input contains duplicate keys, when the chosen policy is to reject duplicates.</p></error><error class="JS" code="0004" label="JSON: not schema-aware." type="dynamic"><p>Raised by <function>fn:json-to-xml</function> if validation 
                  is requested when the processor does not support schema validation or typed nodes.</p></error><error class="JS" code="0005" label="Invalid options." type="dynamic"><p>Raised by functions such as <function>map:merge</function>, <function>fn:parse-json</function>,
                  and <function>fn:xml-to-json</function> if the <code nobreak="false">$options</code> map contains an invalid entry.</p></error><error class="JS" code="0006" label="Invalid XML representation of JSON." type="dynamic"><p>Raised by <function>fn:xml-to-json</function> if the XML input does not
                  conform to the rules for the XML representation of JSON.</p></error><error class="JS" code="0007" label="Bad JSON escape sequence." type="dynamic"><p>Raised by <function>fn:xml-to-json</function> if the XML input uses the attribute
                  <code nobreak="false">escaped="true"</code> or <code nobreak="false">escaped-key="true"</code>, and the corresponding string
                  or key contains an invalid JSON escape sequence.</p></error><error class="JS" code="0008" label="Cannot convert element to map." type="dynamic"><p>Raised by <function>fn:element-to-map</function> if the layout selected for converting
                  elements of a given name is unsuitable for an element node with that name, or
                  if the conversion plan explicitly defines the processing of a particular
               element as an error.</p></error><error class="NS" code="0004" label="No namespace found for prefix." type="dynamic"><p>Raised by <function>fn:resolve-QName</function> and analogous functions if a supplied QName has a 
                  prefix that has no binding to a namespace.</p></error><error class="NS" code="0005" label="Base-uri not defined in the static context." type="dynamic"><p>Raised by <function>fn:resolve-uri</function> if no base URI is available for resolving a relative URI.</p></error><error class="PA" code="0001" label="Origin node is not an ancestor of the target node." type="dynamic"><p>Raised by <function>fn:path</function> if the node supplied in the <code nobreak="false">origin</code>
                  option is not an ancestor of the <code nobreak="false">$node</code> whose relative path is required.</p></error><error class="QM" code="0001" label="Module URI is a zero-length string." type="dynamic"><p>Raised by <function>fn:load-xquery-module</function> if the supplied module URI is zero-length.</p></error><error class="QM" code="0002" label="Module URI not found." type="dynamic"><p>Raised by <function>fn:load-xquery-module</function> if no module can be found with the supplied module URI.</p></error><error class="QM" code="0003" label="Static error in dynamically loaded XQuery module." type="dynamic"><p>Raised by <function>fn:load-xquery-module</function> if a static error 
                  (including a statically detected type error) is encountered when processing the library module.</p></error><error class="QM" code="0005" label="Parameter for dynamically loaded XQuery module has incorrect type." type="dynamic"><p>Raised by <function>fn:load-xquery-module</function> if a value is supplied for the initial context 
                  item or for an external variable, and the value does not conform to the required
                  type declared in the dynamically loaded module.</p></error><error class="QM" code="0006" label="No suitable XQuery processor available." type="dynamic"><p>Raised by <function>fn:load-xquery-module</function> if no XQuery processor is available supporting the requested
                  XQuery version (or if none is available at all).</p></error><error class="RG" code="0001" label="Invalid value for cast/constructor." type="dynamic"><p>A general-purpose error raised when casting, if a cast between two datatypes is allowed in principle,
               but the supplied value cannot be converted: for example when attempting to cast the string <code nobreak="false">"nine"</code> to an integer.</p></error><error class="RG" code="0002" label="Invalid argument to fn:resolve-uri." type="dynamic"><p>Raised when either argument to <function>fn:resolve-uri</function> is not a valid URI/IRI.</p></error><error class="RG" code="0003" label="fn:zero-or-one called with a sequence containing more than one item." type="dynamic"><p>Raised by <function>fn:zero-or-one</function> if the supplied value contains more than one item.</p></error><error class="RG" code="0004" label="fn:one-or-more called with a sequence containing no items." type="dynamic"><p>Raised by <function>fn:one-or-more</function> if the supplied value is the empty sequence.</p></error><error class="RG" code="0005" label="fn:exactly-one called with a sequence containing zero or more than one item." type="dynamic"><p>Raised by <function>fn:exactly-one</function> if the supplied value is not a singleton sequence.</p></error><error class="RG" code="0006" label="Invalid argument type." type="static"><p>Raised by functions such as <function>fn:max</function>, <function>fn:min</function>, <function>fn:avg</function>, <function>fn:sum</function>
               if the supplied sequence contains values inappropriate to this function.</p></error><error class="RG" code="0008" label="The two arguments to fn:dateTime have inconsistent timezones." type="dynamic"><p>Raised by <function>fn:dateTime</function> if the two arguments both have timezones and the timezones are different.</p></error><error class="RG" code="0009" label="Error in resolving a relative URI against a base URI in fn:resolve-uri." type="dynamic"><p>A catch-all error for <function>fn:resolve-uri</function>, recognizing that the implementation can choose between a variety
               of algorithms and that some of these may fail for a variety of reasons.</p></error><error class="RG" code="0010" label="Invalid date/time." type="dynamic"><p>Raised when the input to <function>fn:parse-ietf-date</function> does not match the prescribed
                  grammar, or when it represents an invalid date/time such as 31 February.</p></error><error class="RG" code="0011" label="Invalid radix." type="dynamic"><p>Raised when the radix supplied to <function>fn:parse-integer</function> is not in the range 2 to 36.</p></error><error class="RG" code="0012" label="Invalid digits." type="dynamic"><p>Raised when the digits in the string supplied to <function>fn:parse-integer</function> are not in the range appropriate
                  to the chosen radix.</p></error><error class="RX" code="0001" label="Invalid regular expression flags." type="static"><p>Raised by regular expression functions such as <function>fn:matches</function> and <function>fn:replace</function> if the
               regular expression flags contain a character other than <code nobreak="false">i</code>, <code nobreak="false">m</code>, <code nobreak="false">q</code>, <code nobreak="false">s</code>, or <code nobreak="false">x</code>.</p></error><error class="RX" code="0002" label="Invalid regular expression." type="dynamic"><p>Raised by regular expression functions such as <function>fn:matches</function> and <function>fn:replace</function> if the
                  regular expression is syntactically invalid.</p></error><error class="RX" code="0004" label="Invalid replacement string." type="dynamic"><p>Raised by <function>fn:replace</function> to report errors in the replacement string.</p></error><error class="RX" code="0005" label="Incompatible arguments for fn:replace." type="dynamic"><p>Raised by <function>fn:replace</function> if both the <code nobreak="false">$replacement</code> 
                  and <code nobreak="false">$action</code> arguments are supplied.</p></error><error class="TY" code="0012" label="Argument to fn:data contains a node that does not have a typed value." type="dynamic"><p>Raised by <function>fn:data</function>, or by implicit atomization, if applied to a node with no typed value,
               the main example being an element validated against a complex type that defines it to have element-only content.</p></error><error class="TY" code="0013" label="The argument to fn:data contains a function item." type="dynamic"><p>Raised by <function>fn:data</function>, or by implicit atomization, if the sequence to be atomized contains
                a function item other than an array.</p></error><error class="TY" code="0014" label="The argument to fn:string is a function item." type="dynamic"><p>Raised by <function>fn:string</function>, or by implicit string conversion, if the input sequence contains
                  a function item.</p></error><error class="UT" code="1170" label="Invalid URI reference." type="dynamic"><p>Raised by <function>fn:unparsed-text</function> or <function>fn:unparsed-text-lines</function>
                  if the <code nobreak="false">$source</code> argument contains a fragment identifier,
                  or if it cannot be resolved to an absolute URI (for example, because the
                  base-URI property in the static context is absent), or if it cannot be used to
                  retrieve the string representation of a resource.</p></error><error class="UT" code="1190" label="Cannot decode external resource." type="dynamic"><p diff="chg" at="2023-06-12">Raised by <function>fn:unparsed-text</function> or <function>fn:unparsed-text-lines</function>
                  if the <code nobreak="false">$encoding</code> argument is not a valid encoding name,
                  if the processor does not support the specified encoding, if the string
                  representation of the retrieved resource contains octets that cannot be decoded
                  into Unicode <termref def="character">characters</termref> using the specified
                  encoding, or if the resulting characters are not
                  <termref def="dt-permitted-character">permitted characters</termref>.</p></error><error class="UT" code="1200" label="Cannot infer encoding of external resource." type="dynamic"><p>Raised by <function>fn:unparsed-text</function> or <function>fn:unparsed-text-lines</function>
                  if the <code nobreak="false">$encoding</code> argument is absent and the processor
                  cannot infer the encoding using external information and the
                  encoding is not UTF-8.</p></error><error class="UR" code="0001" label="Invalid IPv6/IPvFuture authority" type="dynamic"><p>A dynamic error is raised if the authority component of a URI
               contains an open square bracket but no corresponding close square bracket.</p></error><error class="XT" code="0001" label="No suitable XSLT processor available" type="dynamic"><p>A dynamic error is raised if no XSLT processor suitable for evaluating a call on <function>fn:transform</function>
                  is available.</p></error><error class="XT" code="0002" label="Invalid parameters to XSLT transformation" type="dynamic"><p>A dynamic error is raised if the parameters supplied to <function>fn:transform</function> are invalid, for example
                  if two mutually exclusive parameters are supplied. If a suitable XSLT error code is available (for example in the
               case where the requested <code nobreak="false">initial-template</code> does not exist in the stylesheet), that error code should
               be used in preference.</p></error><error class="XT" code="0003" label="XSLT transformation failed" type="dynamic"><p>A dynamic error is raised if an XSLT transformation invoked using <function>fn:transform</function> fails with a
                  static or dynamic error. The XSLT error code is used if available; this error code provides a fallback when no XSLT
                  error code is returned, for example because the processor is an XSLT 1.0 processor.</p></error><error class="XT" code="0004" label="XSLT transformation has been disabled" type="dynamic"><p>A dynamic error is raised if the <function>fn:transform</function> function is invoked when XSLT transformation (or a specific
                  transformation option) has been disabled for security or other reasons.</p></error><error class="XT" code="0006" label="XSLT output contains non-accepted characters" type="dynamic"><p>A dynamic error is raised if the result of the <function>fn:transform</function> function contains characters available
                  only in XML 1.1 and the calling processor cannot handle such characters.</p></error></error-list></div1><div1 id="id-built-in-named-record-types"><head>Built-in named record types</head><changes><change issue="835" PR="1991" date="2025-05-11">
               Named record types used in the signatures of built-in functions are now available as standard
               in the static context.
            </change></changes><p>This appendix lists the named record types that are used in function signatures in this function library,
         and that are available in the static context of every application.</p><p>These definitions are all in the standard function namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>,
         which is normally bound to the prefix <code nobreak="false">fn</code>. Because this will not usually be the default namespace for
         types, the names will usually be written with the prefix <code nobreak="false">fn</code>.</p><ulist><item><p>Record <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#attribute-conversion-plan-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">attribute-conversion-plan-record</loc></p></item><item><p>Record <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#dateTime-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">dateTime-record</loc></p></item><item><p>Record <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#element-conversion-plan-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">element-conversion-plan-record</loc></p></item><item><p>Record <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#load-xquery-module-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">load-xquery-module-record</loc></p></item><item><p>Record <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#parsed-csv-structure-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">parsed-csv-structure-record</loc></p></item><item><p>Record <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#random-number-generator-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">random-number-generator-record</loc></p></item><item><p>Record <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#schema-type-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">schema-type-record</loc></p></item><item><p>Record <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="#uri-structure-record" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">uri-structure-record</loc></p></item></ulist></div1><div1 id="schemata"><head>Schemas</head><changes><change issue="648" PR="924" date="2024-01-09">
               Rules have been added clarifying that users should not be allowed to change the schema for
               the <code nobreak="false">fn</code> namespace.
            </change></changes><p>Two functions in this specification, <function>fn:analyze-string</function> and
         <function>fn:json-to-xml</function>, produce results in the form of an XDM node tree that must conform
         to a specified schema, defined in this appendix. 
         In both cases the elements in the result are in the namespace 
         <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>, which is therefore the target namespace
         of the relevant schema.</p><p diff="add" at="issue648">A processor <rfc2119>may</rfc2119> have built-in knowledge 
            of this schema, or it <rfc2119>may</rfc2119> read it from external files. 
            Any attempt to supply a modified form of this 
            schema will have unpredictable consequences. <emph>Modification</emph> here includes 
            not only actual changes to the text of a schema document, but also actions such as 
            using <code nobreak="false">xs:redefine</code> or <code nobreak="false">xs:override</code>, adding members to substitution 
            groups, or defining derived types. Processors are not <rfc2119>required</rfc2119> to detect and reject 
            such modifications. When validating against this schema, it is <rfc2119>recommended</rfc2119>
            that processors should ignore or reject any <code nobreak="false">xsi:schemaLocation</code> or 
            <code nobreak="false">xsi:type</code> attributes in the instance being validated.</p><p>The schema for this namespace is organized as three schema documents. The first is a simple
         umbrella document that includes the other two. A copy can be found at 
            <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="xpath-functions.xsd" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">xpath-functions.xsd</loc>:</p><pre class="small">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    targetNamespace="http://www.w3.org/2005/xpath-functions"&gt;
    
    &lt;!-- 
     * This is a schema for the namespace http://www.w3.org/2005/xpath-functions
     *
     * The schema is made available under the terms of the W3C software notice and license
     * at http://www.w3.org/Consortium/Legal/copyright-software-19980720
     *
     * The schema includes two schema documents, containing definitions of the structure
     * of the results of the fn:analyze-string and fn:json-to-xml functions respectively.
     *
    --&gt;
    
    &lt;xs:include schemaLocation="analyze-string.xsd"/&gt;
    &lt;xs:include schemaLocation="schema-for-json.xsd"/&gt;
    &lt;xs:include schemaLocation="schema-for-csv.xsd"/&gt;
&lt;/xs:schema&gt;
</pre><div2 id="schema-for-analyze-string"><head>Schema for the result of <function>fn:analyze-string</function></head><p>This schema describes the output of the function <function>fn:analyze-string</function>.</p><p>The schema is reproduced below, and can also be found in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="analyze-string.xsd" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">analyze-string.xsd</loc>:</p><pre class="small">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.w3.org/2005/xpath-functions"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    elementFormDefault="qualified"&gt;
    
    &lt;!-- 
     * This is a schema for the XML representation of JSON used as the target for the
     * function fn:analyze-string()
     *
     * The schema is made available under the terms of the W3C software notice and license
     * at http://www.w3.org/Consortium/Legal/copyright-software-19980720
     *
    --&gt;

    &lt;xs:element name="analyze-string-result" type="fn:analyze-string-result-type"/&gt;
    &lt;xs:element name="match" type="fn:match-type"/&gt;
    &lt;xs:element name="non-match" type="xs:string"/&gt;
    &lt;xs:element name="group" type="fn:group-type"/&gt;
    &lt;xs:element name="lookahead-group" type="fn:lookahead-group-type"/&gt;
    
    &lt;xs:complexType name="analyze-string-result-type" mixed="true"&gt;
        &lt;xs:sequence&gt;
            &lt;xs:choice minOccurs="0" maxOccurs="unbounded"&gt;
                &lt;xs:element ref="fn:match"/&gt;
                &lt;xs:element ref="fn:non-match"/&gt;
            &lt;/xs:choice&gt;
        &lt;/xs:sequence&gt;
    &lt;/xs:complexType&gt;
        
    &lt;xs:complexType name="match-type" mixed="true"&gt;
        &lt;xs:sequence&gt;
            &lt;xs:element ref="fn:group" minOccurs="0" maxOccurs="unbounded"/&gt;
            &lt;xs:element ref="fn:lookahead-group" minOccurs="0" maxOccurs="unbounded"/&gt;
        &lt;/xs:sequence&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="group-type" mixed="true"&gt;
        &lt;xs:sequence&gt;
            &lt;xs:element ref="fn:group" minOccurs="0" maxOccurs="unbounded"/&gt;
        &lt;/xs:sequence&gt;
        &lt;xs:attribute name="nr" type="xs:positiveInteger"/&gt;
    &lt;/xs:complexType&gt;

    &lt;xs:complexType name="lookahead-group-type"&gt;
        &lt;xs:attribute name="nr" type="xs:positiveInteger"/&gt;
        &lt;xs:attribute name="value" type="xs:string"/&gt;
        &lt;xs:attribute name="position" type="xs:positiveInteger"/&gt;
    &lt;/xs:complexType&gt;
 
&lt;/xs:schema&gt;
</pre></div2><div2 id="schema-for-json"><head>Schema for the result of <function>fn:json-to-xml</function></head><p>This schema describes the output of the function <function>fn:json-to-xml</function>, and the input to the
            function <function>fn:xml-to-json</function>. </p><p>The schema is reproduced below, and can also be found in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="schema-for-json.xsd" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">schema-for-json.xsd</loc>:</p><pre class="small">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    targetNamespace="http://www.w3.org/2005/xpath-functions"
    xmlns:j="http://www.w3.org/2005/xpath-functions"&gt;
    
    &lt;!-- 
     * This is a schema for the XML representation of JSON used as the target for the
     * function fn:json-to-xml()
     *
     * The schema is made available under the terms of the W3C software notice and license
     * at http://www.w3.org/Consortium/Legal/copyright-software-19980720
     *
    --&gt;
    
    &lt;xs:element name="map" type="j:mapType"&gt;
        &lt;xs:unique name="unique-key"&gt;
            &lt;xs:selector xpath="*"/&gt;
            &lt;xs:field xpath="@key"/&gt;
            &lt;xs:field xpath="@escaped-key"/&gt;
        &lt;/xs:unique&gt;
    &lt;/xs:element&gt;
    
    &lt;xs:element name="array" type="j:arrayType"/&gt;
    
    &lt;xs:element name="string" type="j:stringType"/&gt;
    
    &lt;xs:element name="number" type="j:numberType"/&gt;
    
    &lt;xs:element name="boolean" type="j:booleanType"/&gt;
    
    &lt;xs:element name="null" type="j:nullType"/&gt;
    
    &lt;xs:complexType name="nullType"&gt;
        &lt;xs:sequence/&gt;
        &lt;xs:anyAttribute processContents="skip" namespace="##other"/&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="booleanType"&gt;
        &lt;xs:simpleContent&gt;
            &lt;xs:extension base="xs:boolean"&gt;
                &lt;xs:anyAttribute processContents="skip" namespace="##other"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:simpleContent&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="stringType"&gt;
        &lt;xs:simpleContent&gt;
            &lt;xs:extension base="xs:string"&gt;
                &lt;xs:attribute name="escaped" type="xs:boolean" use="optional" default="false"/&gt;
                &lt;xs:anyAttribute processContents="skip" namespace="##other"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:simpleContent&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:simpleType name="finiteNumberType"&gt;
        &lt;xs:restriction base="xs:double"&gt;
            &lt;!-- exclude positive and negative infinity, and NaN --&gt;
            &lt;xs:minExclusive value="-INF"/&gt;
            &lt;xs:maxExclusive value="INF"/&gt;
        &lt;/xs:restriction&gt;
    &lt;/xs:simpleType&gt;
    
    &lt;xs:complexType name="numberType"&gt;
        &lt;xs:simpleContent&gt;
            &lt;xs:extension base="j:finiteNumberType"&gt;
                &lt;xs:anyAttribute processContents="skip" namespace="##other"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:simpleContent&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="arrayType"&gt;
        &lt;xs:choice minOccurs="0" maxOccurs="unbounded"&gt;
            &lt;xs:element ref="j:map"/&gt;
            &lt;xs:element ref="j:array"/&gt;
            &lt;xs:element ref="j:string"/&gt;
            &lt;xs:element ref="j:number"/&gt;
            &lt;xs:element ref="j:boolean"/&gt;
            &lt;xs:element ref="j:null"/&gt;
        &lt;/xs:choice&gt;
        &lt;xs:anyAttribute processContents="skip" namespace="##other"/&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="mapWithinMapType"&gt;
        &lt;xs:complexContent&gt;
            &lt;xs:extension base="j:mapType"&gt;
                &lt;xs:attributeGroup ref="j:key-group"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:complexContent&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="arrayWithinMapType"&gt;
        &lt;xs:complexContent&gt;
            &lt;xs:extension base="j:arrayType"&gt;
                &lt;xs:attributeGroup ref="j:key-group"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:complexContent&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="stringWithinMapType"&gt;
        &lt;xs:simpleContent&gt;
            &lt;xs:extension base="j:stringType"&gt;
                &lt;xs:attributeGroup ref="j:key-group"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:simpleContent&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="numberWithinMapType"&gt;
        &lt;xs:simpleContent&gt;
            &lt;xs:extension base="j:numberType"&gt;
                &lt;xs:attributeGroup ref="j:key-group"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:simpleContent&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="booleanWithinMapType"&gt;
        &lt;xs:simpleContent&gt;
            &lt;xs:extension base="j:booleanType"&gt;
                &lt;xs:attributeGroup ref="j:key-group"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:simpleContent&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="nullWithinMapType"&gt;
        &lt;xs:attributeGroup ref="j:key-group"/&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:complexType name="mapType"&gt;
        &lt;xs:choice minOccurs="0" maxOccurs="unbounded"&gt;
            &lt;xs:element name="map" type="j:mapWithinMapType"&gt;
                &lt;xs:unique name="unique-key-2"&gt;
                    &lt;xs:selector xpath="*"/&gt;
                    &lt;xs:field xpath="@key"/&gt;
                &lt;/xs:unique&gt;
            &lt;/xs:element&gt;
            &lt;xs:element name="array" type="j:arrayWithinMapType"/&gt;            
            &lt;xs:element name="string" type="j:stringWithinMapType"/&gt;   
            &lt;xs:element name="number" type="j:numberWithinMapType"/&gt;
            &lt;xs:element name="boolean" type="j:booleanWithinMapType"/&gt;
            &lt;xs:element name="null" type="j:nullWithinMapType"/&gt;
        &lt;/xs:choice&gt;
        &lt;xs:anyAttribute processContents="skip" namespace="##other"/&gt;
    &lt;/xs:complexType&gt;
    
    &lt;xs:attributeGroup name="key-group"&gt;
        &lt;xs:attribute name="key" type="xs:string" use="required"/&gt;
        &lt;xs:attribute name="escaped-key" type="xs:boolean" use="optional" default="false"/&gt;
    &lt;/xs:attributeGroup&gt;
    
&lt;/xs:schema&gt;
</pre></div2><div2 id="schema-for-csv"><head>Schema for the result of <function>fn:csv-to-xml</function></head><p>This schema describes the output of the function <function>fn:csv-to-xml</function>.</p><p>The schema is reproduced below, and can also be found in <loc xmlns:xlink="http://www.w3.org/1999/xlink" href="schema-for-csv.xsd" xlink:type="simple" xlink:show="replace" xlink:actuate="onRequest">schema-for-csv.xsd</loc>:</p><pre class="small">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    targetNamespace="http://www.w3.org/2005/xpath-functions"
    xmlns:csv="http://www.w3.org/2005/xpath-functions"&gt;

    &lt;!--
     * This is a schema for the XML representation of CSV used as the target for the
     * function fn:csv-to-xml()
     *
     * The schema is made available under the terms of the W3C software notice and license
     * at http://www.w3.org/Consortium/Legal/copyright-software-19980720
     *
    --&gt;

    &lt;xs:element name="csv" type="csv:csvType"/&gt;

    &lt;xs:element name="columns" type="csv:columnsType"/&gt;

    &lt;xs:element name="rows" type="csv:rowsType"/&gt;

    &lt;xs:element name="column" type="csv:columnFieldType"/&gt;

    &lt;xs:element name="row" type="csv:rowType"/&gt;

    &lt;xs:element name="field" type="csv:fieldType"/&gt;

    &lt;xs:complexType name="csvType"&gt;
        &lt;xs:sequence&gt;
            &lt;xs:element ref="csv:columns" minOccurs="0" maxOccurs="1"/&gt;
            &lt;xs:element ref="csv:rows" minOccurs="1" maxOccurs="1"/&gt;
        &lt;/xs:sequence&gt;
    &lt;/xs:complexType&gt;

    &lt;xs:complexType name="columnsType"&gt;
        &lt;xs:sequence&gt;
            &lt;xs:element ref="csv:column" minOccurs="0" maxOccurs="unbounded"/&gt;
        &lt;/xs:sequence&gt;
    &lt;/xs:complexType&gt;

    &lt;xs:complexType name="rowsType"&gt;
        &lt;xs:sequence&gt;
            &lt;xs:element ref="csv:row" minOccurs="0" maxOccurs="unbounded"/&gt;
        &lt;/xs:sequence&gt;
    &lt;/xs:complexType&gt;

    &lt;xs:complexType name="rowType"&gt;
        &lt;xs:sequence&gt;
            &lt;xs:element ref="csv:field" minOccurs="0" maxOccurs="unbounded"/&gt;
        &lt;/xs:sequence&gt;
    &lt;/xs:complexType&gt;

    &lt;xs:complexType name="columnFieldType"&gt;
        &lt;xs:simpleContent&gt;
            &lt;xs:extension base="xs:string"&gt;
                &lt;xs:anyAttribute processContents="skip" namespace="##other"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:simpleContent&gt;
    &lt;/xs:complexType&gt;

    &lt;xs:complexType name="fieldType"&gt;
        &lt;xs:simpleContent&gt;
            &lt;xs:extension base="csv:columnFieldType"&gt;
                  &lt;xs:attribute name="column" type="xs:string" use="optional"/&gt;
            &lt;/xs:extension&gt;
        &lt;/xs:simpleContent&gt;
    &lt;/xs:complexType&gt;
&lt;/xs:schema&gt;
</pre></div2></div1><inform-div1 id="glossary"><head>Glossary</head><?glossary?></inform-div1><inform-div1 id="other-functions"><head>Functions defined elsewhere</head><p>This Appendix describes some sources of functions that fall outside the scope of the function library defined
         in this specification. It includes both function specifications and function implementations. Inclusion of a function
         in this appendix does not constitute any kind of recommendation or endorsement; neither is omission from this appendix
         to be construed negatively. This Appendix does not attempt to give any information about licensing arrangements for
         these function specifications or implementations.</p><div2 id="functions-in-other-w3c-specs"><head>XPath Functions Defined in Other W3C Recommendations</head><p>A number of W3C Recommendations make use of XPath, and in some cases such Recommmendations define additional
            functions to be made available when XPath is used in a specific host language.</p><div3 id="functions-defined-in-XSLT"><head>Functions Defined in XSLT</head><p>The various versions of XSLT have all included additional functions intended to be available only when XPath
               is used within XSLT, and not in other host language environments. Some of these functions were originally defined
               in XSLT, and subsequently migrated into the core function library defined in this specification.</p><p>Generally, the reason that functions have been defined in XSLT rather than in the core library has been that
               they required additional static or dynamic context information.</p><p>XSLT-defined functions share the core namespace <code nobreak="false">http://www.w3.org/2005/xpath-functions</code> (but in XPath 1.0
               and XSLT 1.0, no namespace was defined for these functions).</p><p>The following table lists all functions that have been defined in XSLT, and summarizes their current status.</p><table role="data"><thead><tr><th rowspan="1" colspan="1">Function name</th><th rowspan="1" colspan="1">Availability</th></tr></thead><tbody><tr><td rowspan="1" colspan="1">fn:accumulator-after</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:accumulator-before</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:apply-templates</td><td rowspan="1" colspan="1">XSLT 4.0</td></tr><tr><td rowspan="1" colspan="1">fn:available-system-properties</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:character-map</td><td rowspan="1" colspan="1">XSLT 4.0</td></tr><tr><td rowspan="1" colspan="1">fn:collation-key</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">fn:copy-of</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:current</td><td rowspan="1" colspan="1">XSLT 1.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:current-group</td><td rowspan="1" colspan="1">XSLT 2.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:current-grouping-key</td><td rowspan="1" colspan="1">XSLT 2.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:current-merge-group</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:current-merge-key</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:current-merge-key-array</td><td rowspan="1" colspan="1">XSLT 4.0</td></tr><tr><td rowspan="1" colspan="1">fn:current-output-uri</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:document</td><td rowspan="1" colspan="1">XSLT 1.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:element-available</td><td rowspan="1" colspan="1">XSLT 1.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:format-date</td><td rowspan="1" colspan="1">Originally XSLT 2.0, then XPath 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:format-dateTime</td><td rowspan="1" colspan="1">Originally XSLT 2.0, then XPath 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:format-number</td><td rowspan="1" colspan="1">Originally XSLT 1.0 and 2.0; then XPath 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:format-time</td><td rowspan="1" colspan="1">Originally XSLT 2.0; then XPath 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:function-available</td><td rowspan="1" colspan="1">XSLT 1.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:generate-id</td><td rowspan="1" colspan="1">Originally XSLT 1.0 and 2.0; then XPath 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:json-to-xml</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">fn:key</td><td rowspan="1" colspan="1">XSLT 1.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:map-for-key</td><td rowspan="1" colspan="1">XSLT 4.0</td></tr><tr><td rowspan="1" colspan="1">fn:regex-group</td><td rowspan="1" colspan="1">XSLT 2.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:regex-groups</td><td rowspan="1" colspan="1">XSLT 4.0</td></tr><tr><td rowspan="1" colspan="1">fn:snapshot</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:stream-available</td><td rowspan="1" colspan="1">XSLT 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:system-property</td><td rowspan="1" colspan="1">XSLT 1.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:type-available</td><td rowspan="1" colspan="1">XSLT 2.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:unparsed-entity-public-id</td><td rowspan="1" colspan="1">XSLT 2.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:unparsed-entity-uri</td><td rowspan="1" colspan="1">XSLT 1.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:unparsed-text</td><td rowspan="1" colspan="1">Originally XSLT 2.0; then XPath 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:unparsed-text-available</td><td rowspan="1" colspan="1">Originally XSLT 2.0; then XPath 3.0 and later</td></tr><tr><td rowspan="1" colspan="1">fn:xml-to-json</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:contains</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:entry</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:find</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:for-each</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:get</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:keys</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:merge</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:put</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:remove</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr><tr><td rowspan="1" colspan="1">map:size</td><td rowspan="1" colspan="1">Originally XSLT 3.0, then XPath 3.1 and later</td></tr></tbody></table><note><p>XSLT 3.0 was well advanced when work started on XPath 3.1, but
               XPath 3.1 appeared as a Recommendation before XSLT 3.0 reached that status.</p></note></div3><div3 id="functions-defined-in-XForms"><head>Functions Defined in XForms</head><p>XForms 1.1 is based on XPath 1.0. It adds the following functions to the set defined in XPath 1.0, using the same
               namespace:</p><p><code nobreak="false">boolean-from-string</code>, <code nobreak="false">is-card-number</code>, <code nobreak="false">avg</code>, <code nobreak="false">min</code>, <code nobreak="false">max</code>, 
                  <code nobreak="false">count-non-empty</code>, <code nobreak="false">index</code>, <code nobreak="false">power</code>, <code nobreak="false">random</code>, <code nobreak="false">compare</code>,
                  <code nobreak="false">if</code>, <code nobreak="false">property</code>, 
               <code nobreak="false">digest</code>, <code nobreak="false">hmac</code>, <code nobreak="false">local-date</code>, <code nobreak="false">local-dateTime</code>, <code nobreak="false">now</code>, 
                  <code nobreak="false">days-from-date</code>, <code nobreak="false">days-to-date</code>, <code nobreak="false">seconds-from-dateTime</code>, <code nobreak="false">seconds-to-dateTime</code>,
               <code nobreak="false">adjust-dateTime-to-timezone</code>, <code nobreak="false">seconds</code>, <code nobreak="false">months</code>, <code nobreak="false">instance</code>, 
                  <code nobreak="false">current</code>, <code nobreak="false">id</code>, <code nobreak="false">context</code>, <code nobreak="false">choose</code>, <code nobreak="false">event</code>.</p><p>XForms 2.0 was first published as a W3C Working Draft, and subsequently as a W3C Community Group specification. These
               draft specifications do not include any additional functions beyond those in the core XPath specification.</p></div3><div3 id="xquery-update"><head>Function Defined in XQuery Update 1.0</head><p>The XQuery Update 1.0 specification defines one additional function in the core namespace
                  <code nobreak="false">http://www.w3.org/2005/xpath-functions</code>, namely <code role="example" nobreak="false">fn:put</code>. This function can be used
               to write a document to external storage. It is thus unusual in that it has side-effects; the XQuery Update 1.0
               specification defines semantics for updating expressions including this function.</p><p>Although XQuery Update 1.0 is defined as an extension of XQuery 1.0, a number of implementers have adapted it,
               in a fairly intuitive way, to work with later versions of XQuery. At the time of this publication, later versions of the
               XQuery Update specification remain at Working Draft status.</p></div3></div2><div2 id="functions-defined-by-community-groups"><head>Functions Defined by Community Groups</head><p>A number of community groups, with varying levels of formal organization, have defined specifications for
            additional function libraries to augment the core functions defined in this specification. Many of the resulting
            function specifications have implementations available for popular XPath, XQuery, and XSLT processors, though
            the level of support is highly variable.</p><p>The first such group was EXSLT. This activity was primarily concerned with augmenting the capability of
            XSLT 1.0, and many of its specifications were overtaken by core functions that became available in XPath 2.0.
            EXSLT defined a number of function modules covering:</p><slist><sitem>Dates and Times</sitem><sitem>Dynamic XPath Evaluation</sitem><sitem>Common (containing most notably the widely used <code nobreak="false">node-set</code> function)</sitem><sitem>Math (<code nobreak="false">max</code>, <code nobreak="false">min</code>, <code nobreak="false">abs</code>, and trigonometric functions)</sitem><sitem>Random Number Generation</sitem><sitem>Regular Expressions</sitem><sitem>Sets (operations on sets of nodes including set intersection and difference)</sitem><sitem>String Manipulation (tokenize, replace, join and split, etc.)</sitem></slist><p>Specifications from the EXSLT group can be found at <bibref ref="exslt"/>.</p><p>A renewed attempt to define additional function libraries using XPath 2.0 as its baseline formed
            under the name EXPath. Again, the specifications are in various states of maturity and stability, and
            implementation across popular processors is patchy. At the time of this publication the function libraries that
            exist in stable published form include:</p><slist><sitem>Binary (functions for manipulating binary data)</sitem><sitem>File Handling (reading and writing files)</sitem><sitem>Geospatial (handling of geographic data)</sitem><sitem>HTTP Client (sending HTTP requests)</sitem><sitem>ZIP Facility (reading and creating ZIP files or similar archives)</sitem></slist><p>The EXPath community has also been engaged in other related projects, such as defining packaging
            standards for distribution of XSLT/XQuery components, and tools for unit testing. Its specifications
            can be found at <bibref ref="expath"/>.</p><p>A third activity has operated under the name EXQuery, which as the name suggests has focused
            on extensions to XQuery. EXQuery has published a single specification, RestXQ, which is primarily a 
            system of function annotations allowing XQuery functions to act as endpoints for RESTful services.
            It also includes some simple functions to assist with the creation of such services. The RestXQ specification
            can be found at <bibref ref="exquery"/>.</p></div2><div2 id="functx-library"><head>The FunctX Library</head><p>Many useful functions can be written in XSLT or XQuery, and in this case the function implementations
                  themselves can be portable across different XSLT and XQuery processors. This section describes one such library.</p><p>FunctX is an open-source library of general-purpose functions, supplied in the form of XQuery 1.0 and XSLT 2.0
               implementations. It contains over a hundred functions. Typical examples of these functions are:</p><slist><sitem>Test whether a string is all-whitespace</sitem><sitem>Trim leading and trailing whitespace</sitem><sitem>Test whether all the values in a sequence are distinct</sitem><sitem>Capitalize the first character of a string</sitem><sitem>Change the namespace of all elements in a tree</sitem><sitem>Get the number of days in a given month</sitem><sitem>Get the first or last day in a given month</sitem><sitem>Get the date of the preceding or following day</sitem><sitem>Ask whether an element has element-only, mixed, or simple content</sitem><sitem>Find the position of a node in a sequence</sitem><sitem>Count words in a string</sitem></slist><p>The FunctX library can be found at <bibref ref="functx"/>.</p></div2></inform-div1><inform-div1 id="impl-def"><head>Implementation-defined features</head><?imp-def-features?></inform-div1><inform-div1 id="changelog" diff="chg" at="2022-11-16"><head>Changes since 3.1</head><div2 id="changes-summary"><head>Summary of Changes</head><?change-log?></div2><div2 id="changes-to-casts-and-constructors"><head>Changes to Casts and Constructor Functions</head><olist><item><p>The keyword for the argument has changed from <code nobreak="false">arg</code> to <code nobreak="false">value</code>.</p></item><item><p>The argument is now optional, and defaults to the context value (which is atomized if necessary).
	           This change aligns constructor functions such as <code nobreak="false">xs:string</code>, <code nobreak="false">xs:boolean</code>,
	              and <code nobreak="false">xs:numeric</code> with <function>fn:string</function>, <function>fn:boolean</function>,
	              and <function>fn:number</function>.</p></item></olist></div2><div2 id="miscellaneous-changes"><head>Miscellaneous Changes</head><olist><item><p>The semantics of the HTML case-insensitive collation 
	              <code nobreak="false">"http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive"</code>
	              are now defined normatively in this specification rather than by reference to the 
	              living HTML5 specification (which has changed since 3.1); and the rules now make ordering explicit rather than leaving
	              it implementation-defined.</p></item><item><p>An option in an <termref def="options">option map</termref> is now rejected if
                it is not described in the specification, if it is not supported by the implementation
                and if its name is in no namespace.</p></item></olist></div2><div2 id="editorial-changes"><head>Editorial Changes</head><p>These changes are not highlighted in the change-marked version of the specification.</p><olist><item><p>The value comparison operators such as <code nobreak="false">eq</code>, <code nobreak="false">lt</code>, and <code nobreak="false">gt</code>
	                 are now defined in <bibref ref="xpath-40"/> by reference to <function>fn:compare</function>
	                 and other functions. The datatype-specific functions <code role="example" nobreak="false">op:XX-equal</code>,
	                 <code role="example" nobreak="false">op:XX-less-than</code>, and <code role="example" nobreak="false">op:XX-greater-than</code>
	                 have therefore been dropped.</p></item><item><p>The names of parameters appearing in function signatures have been changed. This
	           is to reflect the introduction of keyword arguments in XPath 4.0; the names chosen
	           for parameters are now more consistent across the function library.</p><p>In 3.1 and earlier versions, the keywords used in the specification were for documentation
	           purposes only, so these changes do not affect backwards compatibility.</p></item><item><p>Where appropriate, the phrase "the value of <code nobreak="false">$x</code>" has been replaced
	           by the simpler <code nobreak="false">$x</code>. No change in meaning is intended.</p></item><item><p>For functions that take a variable number of arguments, wherever possible
	           the specification now gives a single function signature indicating default values
	           for arguments that may be omitted, rather than multiple signatures.</p></item><item><p>The formal specifications of array functions have been rewritten to use two new
	              primitives: <code role="example" nobreak="false">array:members</code> which converts an array to a sequence of value records, 
	              and <code role="example" nobreak="false">array:of-members</code> which does the inverse. This has enabled many of the
	           functions to be specified more concisely, and with less duplication between similar functions
	           for sequences and arrays.</p></item><item><p>The appendix containing illustrative user-written functions has been dropped;
	           many of these functions are no longer needed.</p></item></olist></div2></inform-div1><inform-div1 id="back-compatibility" diff="chg" at="A"><head>Backward compatibility</head><p>This section summarizes the extent to which this specification is compatible with previous versions.</p><p>Version 4.0 of this function library is fully backwards compatible with version 3.1, except as noted
         below:</p><olist><item><p>In <function>fn:deep-equal</function>, and in other functions such as <function>fn:distinct-values</function>
              that refer to <function>fn:deep-equal</function>, the rules for comparing values of different numeric types 
                 (for example, <code nobreak="false">xs:double</code> and <code nobreak="false">xs:decimal</code>) have changed. 
                 In previous versions of the specification, <code nobreak="false">xs:decimal</code> values were converted
              to <code nobreak="false">xs:double</code>, leading to a possible loss of precision. This could make 
              comparisons non-transitive, leading to problems when grouping,
              and potentially (depending on the sort algorithm) with sorting. The problem has been fixed by requiring
              comparisons to be performed based on the exact mathematical value without any loss of precision.</p><p>This means, for example, that <code nobreak="false">deep-equal(0.2, 0.2e0)</code> is now false, whereas in previous
              versions it was true. The two values are not mathematically equal, because the exact decimal equivalent
              of the <code nobreak="false">xs:double</code> value written as <code nobreak="false">0.2e0</code> is 
                 <code nobreak="false">0.200000000000000011102230246251565404236316680908203125</code>.</p><p>The corresponding change has not been made to the <code nobreak="false">=</code> and <code nobreak="false">eq</code> operators,
              because it was found to be too disruptive. For example, if the context node is the element
              <code nobreak="false">&lt;e price="10.0" discount="0.2"/&gt;</code>, there is an expectation that the expression 
                 <code nobreak="false">@price - @discount = 9.8</code> should return true. But (assuming untyped data), the result of
              the subtraction is an <code nobreak="false">xs:double</code> whose precise value is 
                 <code nobreak="false">9.800000000000000710542735760100185871124267578125</code>, so comparing the two values as
              decimals would return false.</p></item><item diff="add" at="2024-06-18"><p>In previous versions, unrecognized options supplied to the <code nobreak="false">$options</code>
              parameter of functions such as <function>fn:parse-json</function> were silently ignored. In
              4.0, they are rejected as a type error, unless they are QNames with a non-absent namespace,
              or are extensions recognized by the implementation.</p></item><item diff="add" at="2022-12-18"><p>In version 4.0, omitting the <code nobreak="false">$value</code> of <function>fn:error</function> has the same
                 effect as setting it to the empty sequence. In 3.1, the effects could be different (the effect of omitting
                 the argument was implementation-defined).</p></item><item diff="add" at="2023-03-13"><p>In version 3.1, the <function>fn:deep-equal</function> function did not merge adjacent text nodes after stripping
                 comments and processing instructions, so the elements <code nobreak="false">&lt;a&gt;abc&lt;!--note1--&gt;def&lt;/code&gt;</code>
                 and <code nobreak="false">&lt;a&gt;abcde&lt;!--note2--&gt;f&lt;/code&gt;</code> were considered non-equal. In version 4.0, 
                 the text nodes are now merged prior to comparison, so these two elements compare equal.</p></item><item><p>In version 3.1, the atomic types <code nobreak="false">xs:hexBinary</code> and <code nobreak="false">xs:base64Binary</code>
              were not mutually comparable under the <code nobreak="false">eq</code> operator, and always compared not equal
              as map keys or under operations such as <code nobreak="false">fn:distinct-values</code> and <code nobreak="false">fn:deep-equal</code>.
              In version 4.0, instances of <code nobreak="false">xs:hexBinary</code> and <code nobreak="false">xs:base64Binary</code> are
              equal if they represent the same octet sequence. This means, for example, that the zero-length
              values <code nobreak="false">xs:hexBinary("")</code> and <code nobreak="false">xs:base64Binary("")</code> can no longer co-exist
              as keys in the same map.</p></item><item diff="add" at="2024-10-01"><p>The format of numeric values in the output of <function>fn:xml-to-json</function> may be different. 
                 In version 3.1, the supplied value was parsed as an <code nobreak="false">xs:double</code> and then serialized
                 using the casting rules, resulting in an input value of 10000000 being output as <code nobreak="false">1e7</code>.
                 In version 4.0, the value is output <emph>as is</emph>, except for any changes (such as stripping
                 of leading zeroes or a leading plus sign) that might be needed to ensure the result is valid JSON.</p></item><item diff="add" at="2023-03-06"><p>In version 4.0, the function signature of <function>fn:namespace-uri-for-prefix</function> constrains the
                 first argument to be either an <code nobreak="false">xs:NCName</code> or a zero-length string (the new coercion rules
                 mean that any string in the form of an <code nobreak="false">xs:NCName</code> is acceptable). If a string is supplied
                 that does not meet these requirements, a type error will be raised. In version 3.1, this was not an error:
                 it came under the rule that when no namespace binding existed for the supplied prefix, the function
                 would return the empty sequence.</p><p>Furthermore, because the expected type of this parameter is no longer <code nobreak="false">xs:string</code>, the
              special coercion rules for <code nobreak="false">xs:string</code> parameters in XPath 1.0 compatibility mode no longer apply.
              For example, supplying <code nobreak="false">xs:duration('PT1H')</code> as the first argument will now raise a
              type error, rather than looking for a namespace binding for the prefix <code nobreak="false">PT1H</code>.</p></item><item diff="add" at="issue687"><p>Version 4.0 makes it clear that the casting of a value other than <code nobreak="false">xs:string</code>
              or <code nobreak="false">xs:untypedAtomic</code> to a list type (whether using a cast expression or a
                 constructor function) is a type error <xerrorref spec="XP" class="TY" code="0004" type="type"/>. 
                 Previously this was defined as an error, but the kind of error and the error code were left unspecified.
              Accordingly, the function signatures of the constructor functions for built-in list types
              have been changed to use an argument type of <code nobreak="false">xs:string?</code>.</p></item><item diff="add" at="issue866"><p>The way that <function>fn:min</function> and <function>fn:max</function> compare numeric values of different types
              has changed. The most noticeable effect is that when these functions are applied to a sequence of
                 <code nobreak="false">xs:integer</code> or <code nobreak="false">xs:decimal</code> values, the result is an <code nobreak="false">xs:integer</code> or 
                 <code nobreak="false">xs:decimal</code>, rather than the result of converting this to an <code nobreak="false">xs:double</code>.</p></item><item diff="add" at="issue780"><p>The type of the third argument of <function>fn:format-number</function> has 
                 changed from <code nobreak="false">xs:string</code> to <code nobreak="false">(xs:string | xs:QName)</code>.
                 Because the expected type of this parameter is no longer <code nobreak="false">xs:string</code>, the
                 special coercion rules for <code nobreak="false">xs:string</code> parameters no longer apply.
                 For example, it is no
              longer possible to supply an instance of <code nobreak="false">xs:anyURI</code> or (when XPath 1.0 compatibility
              mode is in force) an instance of <code nobreak="false">xs:boolean</code> or <code nobreak="false">xs:duration</code>.</p></item><item diff="add" at="issue1725"><p>When <function>map:put</function> replaces an entry in a map with a new value for an
              existing key, in the case where the existing key and the new key differ (for example,
              if they have different type annotations), it is no longer guaranteed that the new
              entry includes the new key rather than the existing key.</p></item><item><p>In regular expressions, the assertions <code nobreak="false">^</code> and <code nobreak="false">$</code> can no longer be
              followed by a quantifier. This is because (a) a quantifier that allows zero occurrences means
              that the assertion will always match, and (b) a quantifier that allows multiple occurrences
              has no effect. Processors may provide an option that allows such regular expressions to be
              accepted for compatibility reasons.</p></item><item><p>The <function>index-of</function> now treats <code nobreak="false">NaN</code> as equal to <code nobreak="false">NaN</code>.</p></item></olist><p>For compatibility issues regarding earlier versions, see the 3.1 version of this specification.</p></inform-div1></back></spec><!--XSLT Processor: Saxonica-->